diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..11fc0aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.o + +/test/void +/test/int +/test/float +/test/string +/test/cptr +/test/class +/test/module +/test/wrong_type +/test/wrong_arg_num + +a.out +*.exe + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c95ac2e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +language: cpp +compiler: + - gcc-4.8 +script: + - cd codegen + - make + - cd .. + - git clone https://github.com/dycoon/mruby_dycoon.git + - cd mruby_dycoon + - make + - cd .. + - cd test + - MRUBY=../mruby_dycoon CXX=g++-4.8 make + - ./test.sh +install: + - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test + - sudo apt-get -qq update + - sudo apt-get -qq install g++-4.8 +notifications: + email: false + diff --git a/MIT-LICENSE.txt b/MIT-LICENSE.txt index ba5ef3b..70568da 100644 --- a/MIT-LICENSE.txt +++ b/MIT-LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2013 Keita Obo +Copyright (c) 2013 - 2014 Keita Obo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b6f0db4 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +.PHONY: all clean test + +all: + make -C codegen + +clean: + make -C test clean + +clean-all: clean + make -C codegen clean + +test: all + make -C test test + +# diff --git a/README.md b/README.md new file mode 100644 index 0000000..0b2179d --- /dev/null +++ b/README.md @@ -0,0 +1,283 @@ +mrubybind - Binding library for mruby/C++ +========================================= + +mrubybind automatically creates C function/class-method binder for [mruby](https://github.com/mruby/mruby), +using C++ template partial specialization. +require C++11. because it use std::function and lambda. + +## Usage + +### How to use mrubybind in your project + +1. Put following source codes into your project. + * mrubybind.cc + * mrubybind.h +2. Include "mrubybind.h" +3. Use `MrubyBind` instance to bind C function/class-method to mruby. + +## Examples + +### Bind C function and call it from mruby + +1. C function (Any type you want): + + ```c++ + int square(int x) { + return x * x; + } + ``` + +2. Bind it using mrubybind `bind` method: + + ```c++ + #include "mrubybind.h" + + void install_square_function(mrb_state* mrb) { + mrubybind::MrubyBind b(mrb); + b.bind("square", square); + } + ``` + + You can throw away `MrubyBind` instance after binding function. + +3. Call it from mruby: + + ```ruby + puts square(1111) #=> 1234321 + ``` + +### Bind C++ class and method and create its instance from mruby + +1. C++ class: + + ```c++ + class Foo { + public: + Foo(int x) : x_(x) { + cout << "Foo::ctor(" << x << ")" << endl; + } + virtual ~Foo() { + cout << "Foo::dtor()" << endl; + } + int bar(int y) { + return x_ + y; + } + static int baz(int z) { + return z * z; + } + + private: + int x_; + }; + ``` + +2. Bind C++ class using mrubybind `bind_class`, `bind_instance_method` and + `bind_static_method` method: + + ```c++ + #include "mrubybind.h" + + // Helper function for constructor. + Foo* new_foo(int x) { + return new Foo(x); + } + + void install_foo_class(mrb_state* mrb) { + mrubybind::MrubyBind b(mrb); + b.bind_class("Foo", new_foo); + b.bind_instance_method("Foo", "bar", &Foo::bar); + b.bind_static_method("Foo", "baz", &Foo::baz); + } + ``` + +3. Call it from mruby: + + ```ruby + foo = Foo.new(123) #=> Foo::ctor(123) + p foo #=> # + p foo.bar(567) #=> 690 + p Foo.baz(9999) #=> 99980001 + #=> Foo::dtor() + ``` + +### Bind functions under some module + +1. Pass `RClass*` instace for `MrubyBind` constructor: + + ```c++ + void install(mrb_state* mrb) { + RClass* mod = mrb_define_module(mrb, "YourModule"); + mrubybind::MrubyBind b(mrb, mod); + b.bind("foo", foo); + } + ``` + + You can use `YourModule.foo` function from mruby. + +### Bind constant + +1. Use `bind_const` method: + + ```c++ + void install(mrb_state* mrb) { + mrubybind::MrubyBind b(mrb); + b.bind_const("FOO", FOO_VALUE); + } + ``` + +### Call block from C++ code + +1. define C++ function having callback function + + ```c++ + std::string call_block(mrubybind::FuncPtr f) { + if(f) + { + f.func()(23); + } + return "called\n"; + } + ``` + +2. Bind it using mrubybind: + + ```c++ + #include "mrubybind.h" + + void install_call_block_function(mrb_state* mrb) { + mrubybind::MrubyBind b(mrb); + b.bind("call_block", call_block); + } + ``` + +3. Call it from mruby: + + ```ruby + puts call_block { |a0| + puts "a0 = #{a0}" + } + ``` + +### Manage Registered Class Instance + +1. Define C++ function managing class instance: + + ```c++ + class ClassValue{ + public: + int a; + + ClassValue(){ + a = 7; + } + + ~ClassValue(){ + + } + + void decriment(){ + a--; + } + }; + + std::shared_ptr create_class_value() + { + return std::shared_ptr(new ClassValue()); + } + + void class_value_increment(std::shared_ptr cv) + { + cv->a++; + } + + int class_value_get_a(std::shared_ptr cv) + { + return cv->a; + } + + void class_value_decriment(std::shared_ptr cv) + { + cv->decriment(); + } + ``` + +2. Register class and bind function: + + ```c++ + #include "mrubybind.h" + + void install_class_value_function(mrb_state* mrb) { + mrubybind::MrubyBind b(mrb); + b.bind("create_class_value", create_class_value); + b.bind_class >("ClassValue"); + b.bind("class_value_increment", class_value_increment); + b.bind("class_value_get_a", class_value_get_a); + b.bind_custom_method(NULL, "ClassValue", "decriment", class_value_decriment); + } + ``` + +3. Call it from mruby: + + ```ruby + cv = create_class_value + puts "cv -> #{class_value_get_a(cv)}" + class_value_increment(cv) + puts "cv -> #{class_value_get_a cv}" + cv.decriment + puts "cv -> #{class_value_get_a cv}" + ``` + +### Refering to mruby object + +1. Recieve mruby object reference function: + + ```c++ + mrubybind::MrubyRef mruby_ref; + + void set_mruby_ref(mrubybind::MrubyRef r){ + mruby_ref = r; + } + ``` + +2. Bind it using mrubybind: + + ```c++ + #include "mrubybind.h" + + void install_mruby_ref_function(mrb_state* mrb) { + mrubybind::MrubyBind b(mrb); + b.bind("set_mruby_ref", set_mruby_ref); + } + ``` + +3. Send from mruby code: + + ```ruby + set_mruby_ref "3test" + ``` + +4. Manage reference of mruby object on C++: + + ```c++ + std::cout << "mruby_ref = " << mruby_ref.to_s() << std::endl; + std::cout << "mruby_ref = " << mruby_ref.to_i() << std::endl; + std::cout << "mruby_ref = " << mruby_ref.call("gsub", "te", "toa").to_s() << std::endl; + ``` + +## Supported types +| C++ type | mruby type | +|--------------------------|-------------------------| +| int, unsigned int | Fixnum | +| float, double | Float | +| const char*, string | String | +| bool | TrueClass or FalseClass | +| void* | Object | +| mrubybind::FuncPtr<...> | Proc | +| mrubybind::MrubyRef | Any Mruby Object | +| registered class | registered class | + +See [mrubybind.h](https://github.com/ktaobo/mrubybind/blob/master/mrubybind.h). + +# License + +MIT license. diff --git a/codegen/Makefile b/codegen/Makefile index ded187f..4f4ae8e 100644 --- a/codegen/Makefile +++ b/codegen/Makefile @@ -1,14 +1,22 @@ -all: ../mrubybind.dat ../mrubybind.inc +TARGET= ../mrubybind.h -clean: - echo '' -../mrubybind.dat: binder.rb - ${MRUBY}/bin/mrbc -Bbinder binder.rb - mv binder.c ../mrubybind.dat +all: $(TARGET) + +clean: + rm -rf $(TARGET) -../mrubybind.inc: gen_template.rb - ruby gen_template.rb > ../mrubybind.inc +../mrubybind.h: mrubybind.1.h mrubybind.3.h mrubybind_types.1.h mrubybind_types.3.h gen_template.rb + (echo "// Do not modify this file directly, this is generated" && \ + cat mrubybind.1.h mrubybind_types.1.h && \ + ruby gen_template.rb && \ + cat mrubybind_types.3.h mrubybind.3.h) > $@ + +../mrubybind_types_generated.h: gen_types_template.rb + ruby gen_types_template.rb > ../mrubybind_types_generated.h + +../mrubybind_call_generated.h: gen_call_template.rb + ruby gen_call_template.rb > ../mrubybind_call_generated.h # diff --git a/codegen/binder.rb b/codegen/binder.rb deleted file mode 100644 index 5359a3b..0000000 --- a/codegen/binder.rb +++ /dev/null @@ -1,27 +0,0 @@ -# This code is compiled by mrbc, -# and included into C code. - -module MrubyBind - def MrubyBind.define_function(binder, name, f) - Kernel.send(:define_method, name) do |*args| - MrubyBind::call_cfunc(binder, f, *args) - end - end - - def MrubyBind.create_class(binder, klass, f) - k = Kernel.const_set(klass, Class.new) - k.class_eval do - define_method(:initialize) do |*args| - @instance = MrubyBind::call_cfunc(binder, f, *args) - end - end - end - - def MrubyBind.define_class_method(binder, klass, func, f) - Kernel.const_get(klass).class_eval do - define_method(func) do |*args| - MrubyBind::call_cmethod(binder, @instance, f, *args) - end - end - end -end diff --git a/codegen/gen_call_template.rb b/codegen/gen_call_template.rb new file mode 100644 index 0000000..773e629 --- /dev/null +++ b/codegen/gen_call_template.rb @@ -0,0 +1,59 @@ + + +MAX_PARAM = 17 + +HEADER = <::get(mrb, args[i]) +\#define CHECK(i) {if(!Type::check(mrb, args[i])) return RAISE(i);} +\#define RAISE(i) raise(mrb, i, Type::TYPE_NAME, args[i]) + +EOD + +TMPL = <MrubyRef call(%ARGS%){ + MrubyArenaStore mas(mrb); + //%ASSERTS% + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), %ARG_VALS%)); + } + +EOD + +FOOTER = <::ret(mrb, a#{i})"}).join(', ') + end + + table = { + '%PARAMS%' => params, + '%NPARAM%' => nparam.to_s, + '%ARGS%' => args, + '%CLASSES%' => classes, + '%ASSERTS%' => asserts, + '%ARG_VALS%' => arg_vals, + } + + return str.gsub(/(#{table.keys.join('|')})/) {|k| table[k]} +end + +print HEADER +(1..MAX_PARAM).each do |nparam| + print embed_template(TMPL, nparam) +end +print FOOTER diff --git a/codegen/gen_template.rb b/codegen/gen_template.rb index 38e9018..bdf55f1 100644 --- a/codegen/gen_template.rb +++ b/codegen/gen_template.rb @@ -1,100 +1,312 @@ - -MAX_PARAM = 6 - -HEADER = <::get(args[i]) -\#define CHECK(i) Type::check(args[i]) - -EOD - -FUNC_TMPL = < -struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == %NPARAM%);%ASSERTS% - void (*fp)(%PARAMS%) = (void (*)(%PARAMS%))p; - fp(%ARGS%); - return mrb_nil_value(); - } -}; - -// R f(%PARAMS%); -template -struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == %NPARAM%); %ASSERTS% - R (*fp)(%PARAMS%) = (R (*)(%PARAMS%))p; - R result = fp(%ARGS%); - return Type::ret(mrb, result); - } -}; - -EOD - -METHOD_TMPL = < -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == %NPARAM%);%ASSERTS% - typedef void (C::*M)(%PARAMS%); - M method = *(M*)p; - (((C*)o)->*method)(%ARGS%); - return mrb_nil_value(); - } -}; - -// class C { R f(P0) }; -template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == %NPARAM%);%ASSERTS% - typedef R (C::*M)(%PARAMS%); - M method = *(M*)p; - R result = (((C*)o)->*method)(%ARGS%); - return Type::ret(mrb, result); - } -}; - -EOD - -FOOTER = < params, - '%NPARAM%' => nparam.to_s, - '%ARGS%' => args, - '%CLASSES0%' => classes, - '%CLASSES1%' => classes.empty? ? '' : ', ' + classes, - '%ASSERTS%' => asserts - } - - return str.gsub(/(#{table.keys.join('|')})/) {|k| table[k]} -end - -print HEADER -(0..MAX_PARAM).each do |nparam| - print embed_template(FUNC_TMPL, nparam) - print embed_template(METHOD_TMPL, nparam) -end -print FOOTER - -# + +MAX_PARAM = 17 + +HEADER = <::get(mrb, args[i]) +\#define ARGSHIFT(mrb, i, j) Type::get(mrb, args[j]) +\#define CHECK(i) {if(!Type::check(mrb, args[i])) return RAISE(i);} +\#define CHECKSHIFT(i, j) {if(!Type::check(mrb, args[j])) return RAISE(j);} +\#define RAISE(i) raise(mrb, i, Type::TYPE_NAME, args[i]) +\#define CHECKNARG(narg) {if(narg != NPARAM) RAISENARG(narg);} +\#define RAISENARG(narg) raisenarg(mrb, mrb_cfunc_env_get(mrb, 1), narg, NPARAM) + +EOD + +FUNC_TMPL = < +struct Binder { + static const int NPARAM = %NPARAM%; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + %ASSERTS% + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(%PARAMS%) = (void (*)(%PARAMS%))mrb_cptr(cfunc); + fp(%ARGS%); + return mrb_nil_value(); + } +}; + +// R f(%PARAMS%); +template +struct Binder { + static const int NPARAM = %NPARAM%; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + %ASSERTS% + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(%PARAMS%) = (R (*)(%PARAMS%))mrb_cptr(cfunc); + R result = fp(%ARGS%); + return Type::ret(mrb, result); + } +}; + +// C* ctor(%PARAMS%); +template +struct ClassBinder { + static const int NPARAM = %NPARAM%; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + %ASSERTS% + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(%PARAMS%) = (C* (*)(%PARAMS%))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(%ARGS%); + DATA_PTR(self) = instance; + } + return self; + } +}; + +EOD + +METHOD_TMPL = < +struct ClassBinder { + static const int NPARAM = %NPARAM%; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + %ASSERTS% + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(%PARAMS%); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(%ARGS%); + return mrb_nil_value(); + } +}; + +// class C { R f(%PARAMS%) }; +template +struct ClassBinder { + static const int NPARAM = %NPARAM%; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + %ASSERTS% + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(%PARAMS%); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(%ARGS%); + return Type::ret(mrb, result); + } +}; + +EOD + +CUSTOM_METHOD_TMPL = < +struct CustomClassBinder { + static const int NPARAM = %NPARAM% - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + %ASSERTS% + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(%PARAMS%); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance%ARGS1%); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = %NPARAM% - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + %ASSERTS% + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(%PARAMS%); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance%ARGS1%); + return Type::ret(mrb, result); + } +}; + + +EOD + +FOOTER = < params, + '%NPARAM%' => nparam.to_s, + '%ARGS%' => args, + '%CLASSES0%' => classes, + '%CLASSES1%' => classes.empty? ? '' : ', ' + classes, + '%ASSERTS%' => 'CHECKNARG(narg);' + asserts + } + + return str.gsub(/(#{table.keys.join('|')})/) {|k| table[k]} +end + +def embed_template_custom(str, nparam) + if nparam == 0 + params = 'void' + args = '' + classes = '' + asserts = '' + else + params = (0...nparam).map {|i| "P#{i}"}.join(', ') + args = (1...nparam).map {|i| "ARGSHIFT(mrb, #{i}, #{i - 1})"}.join(', ') + classes = (0...nparam).map {|i| "class P#{i}"}.join(', ') + asserts = (1...nparam).map {|i| " CHECKSHIFT(#{i}, #{i - 1});"}.join('') + end + + table = { + '%PARAMS%' => params, + '%NPARAM%' => nparam.to_s, + '%ARGS%' => args, + '%ARGS1%' => args.empty? ? '' : ', ' + args, + '%CLASSES0%' => classes, + '%CLASSES1%' => classes.empty? ? '' : ', ' + classes, + '%ASSERTS%' => 'CHECKNARG(narg);' + asserts + } + + ts = str.gsub(/(#{table.keys.join('|')})/) {|k| table[k]} + + if nparam == 0 + params = 'void' + args = '' + classes = '' + asserts = '' + else + params = (0...nparam).map {|i| (i == 0) ? "P#{i}&" : "P#{i}"}.join(', ') + args = (1...nparam).map {|i| "ARGSHIFT(mrb, #{i}, #{i - 1})"}.join(', ') + classes = (0...nparam).map {|i| "class P#{i}"}.join(', ') + asserts = (1...nparam).map {|i| " CHECKSHIFT(#{i}, #{i - 1});"}.join('') + end + + table = { + '%PARAMS%' => params, + '%NPARAM%' => nparam.to_s, + '%ARGS%' => args, + '%ARGS1%' => args.empty? ? '' : ', ' + args, + '%CLASSES0%' => classes, + '%CLASSES1%' => classes.empty? ? '' : ', ' + classes, + '%ASSERTS%' => 'CHECKNARG(narg);' + asserts + } + + ts += str.gsub(/(#{table.keys.join('|')})/) {|k| table[k]} + + return ts +end + +print HEADER +(0..MAX_PARAM).each do |nparam| + print embed_template(FUNC_TMPL, nparam) + print embed_template(METHOD_TMPL, nparam) + print embed_template_custom(CUSTOM_METHOD_TMPL, nparam) if nparam != 0 +end +print FOOTER + +# diff --git a/codegen/gen_types_template.rb b/codegen/gen_types_template.rb new file mode 100644 index 0000000..905c90b --- /dev/null +++ b/codegen/gen_types_template.rb @@ -0,0 +1,82 @@ + +MAX_PARAM = 17 + +HEADER = <::get(mrb, args[i]) +\#define CHECK(i) {if(!Type::check(mrb, args[i])) return RAISE(i);} +\#define RAISE(i) raise(mrb, i, Type::TYPE_NAME, args[i]) + +EOD + +TYPE_TMPL = < +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](%ARGS%){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {%ARG_VALS%}; + return Type::get(mrb, mrb_yield_argv(mrb, v, %NPARAM%, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(%PARAMS%) +template<%CLASSES%> +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](%ARGS%){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {%ARG_VALS%}; + mrb_yield_argv(mrb, v, %NPARAM%, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +EOD + + +FOOTER = <::ret(mrb, a#{i})"}.join(', ') + args = (0...nparam).map {|i| "P#{i} a#{i}"}.join(', ') + + table = { + '%PARAMS%' => params, + '%NPARAM%' => nparam.to_s, + '%ARG_VALS%' => arg_vals, + '%CLASSES%' => classes, + '%ARGS%' => args, + } + + return str.gsub(/(#{table.keys.join('|')})/) {|k| table[k]} +end + +print HEADER +(1..MAX_PARAM).each do |nparam| + print embed_template(TYPE_TMPL, nparam) +end +print FOOTER + diff --git a/codegen/mrubybind.1.h b/codegen/mrubybind.1.h new file mode 100644 index 0000000..fc001bf --- /dev/null +++ b/codegen/mrubybind.1.h @@ -0,0 +1,36 @@ +/** + * mrubybind - Binding library for mruby/C++ + * + * Usage: + * 1. Prepare a function which you want to call from mruby: + * > int square(int x) { return x * x; } + * + * 2. Create MrubyBind instance: + * > MrubyBind b(mirb) + * + * 3. Bind a function: + * > b.bind("square", square); + * + * 4. You can call it from mruby: + * > puts square(1111) #=> 1234321 + * + * There are other methods to bind constant/class/instance method in + * MrubyBind. Please see the definition of MrubyBind + * (the bottom of this file), or README. + */ +#ifndef __MRUBYBIND_H__ +#define __MRUBYBIND_H__ + +#ifndef __cplusplus +#error mrubybind can be used from C++ only. +#endif + +#include "mruby.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/proc.h" +#include "mruby/variable.h" +//#include "mrubybind_types.h" + +#include +#include diff --git a/codegen/mrubybind.3.h b/codegen/mrubybind.3.h new file mode 100644 index 0000000..cef16a1 --- /dev/null +++ b/codegen/mrubybind.3.h @@ -0,0 +1,190 @@ + +namespace mrubybind { + +//=========================================================================== +// MrubyBind - utility class for binding C functions/classes to mruby. +class MrubyBind { +public: + MrubyBind(mrb_state* mrb); + MrubyBind(mrb_state* mrb, RClass* mod); + ~MrubyBind(); + + // Bind constant value. + template + void bind_const(const char* name, T v) { + MrubyArenaStore store(mrb_); + mrb_define_const(mrb_, mod_, name, Type::ret(mrb_, v)); + } + + template + void bind_const(const char* module_name, const char* class_name, const char* name, T v) { + MrubyArenaStore store(mrb_); + + struct RClass * tc = DefineClass(module_name, class_name); + + mrb_define_const(mrb_, tc, name, Type::ret(mrb_, v)); + } + + // Bind function. + template + void bind(const char* func_name, Func func_ptr) { + MrubyArenaStore store(mrb_); + mrb_sym func_name_s = mrb_intern_cstr(mrb_, func_name); + mrb_value env[] = { + mrb_cptr_value(mrb_, (void*)func_ptr), // 0: c function pointer + mrb_symbol_value(func_name_s), // 1: function name + }; + struct RProc* proc = mrb_proc_new_cfunc_with_env(mrb_, Binder::call, 2, env); + mrb_field_write_barrier(mrb_, (RBasic *)proc, (RBasic *)proc->env); + if (mod_ == mrb_->kernel_module) + mrb_define_method_raw(mrb_, mod_, func_name_s, proc); + else + mrb_define_class_method_raw(mrb_, mod_, func_name_s, proc); + } + + // Bind class. + template + void bind_class(const char* class_name, Func new_func_ptr) { + MrubyArenaStore store(mrb_); + struct RClass *tc = mrb_define_class(mrb_, class_name, mrb_->object_class); + MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA); + BindInstanceMethod(class_name, "initialize", + mrb_cptr_value(mrb_, (void*)new_func_ptr), + ClassBinder::ctor); + } + + // Bind class.(no new func) + template + void bind_class(const char* module_name, const char* class_name) { + MrubyArenaStore store(mrb_); + + struct RClass * tc = DefineClass(module_name, class_name); + std::string name; + if(module_name){ + name += module_name; + name += "::"; + } + name += class_name; + + Type::class_name = name; + Type::class_name = name; + MrubyBindStatus::search(mrb_)->set_class_conversion(name, name, true); + MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA); + BindInstanceMethod(module_name, class_name, "initialize", + mrb_cptr_value(mrb_, NULL), + ClassBinder::ctor); + } + + template + void bind_class(const char* class_name) { + bind_class(NULL, class_name); + } + + // Bind instance method. + template + void bind_instance_method(const char* class_name, const char* method_name, + Method method_ptr) { + MrubyArenaStore store(mrb_); + mrb_value method_pptr_v = mrb_str_new(mrb_, + reinterpret_cast(&method_ptr), + sizeof(method_ptr)); + BindInstanceMethod(class_name, method_name, + method_pptr_v, ClassBinder::call); + } + + // Bind static method. + template + void bind_static_method(const char* module_name, const char* class_name, const char* method_name, + Method method_ptr) { + MrubyArenaStore store(mrb_); + mrb_sym method_name_s = mrb_intern_cstr(mrb_, method_name); + mrb_value env[] = { + mrb_cptr_value(mrb_, (void*)method_ptr), // 0: method pointer + mrb_symbol_value(method_name_s), // 1: method name + }; + struct RProc* proc = mrb_proc_new_cfunc_with_env(mrb_, Binder::call, 2, env); + mrb_field_write_barrier(mrb_, (RBasic *)proc, (RBasic *)proc->env); + struct RClass* klass = GetClass(module_name, class_name); + mrb_define_class_method_raw(mrb_, klass, method_name_s, proc); + } + + template + void bind_static_method(const char* class_name, const char* method_name, + Method method_ptr) { + bind_static_method(NULL, class_name, method_name, + method_ptr); + } + + // Bind custom method. + template + void bind_custom_method(const char* module_name, const char* class_name, const char* method_name, Func func_ptr) { + MrubyArenaStore store(mrb_); + mrb_value (*binder_func)(mrb_state*, mrb_value) = CustomClassBinder::call; + mrb_value original_func_v = mrb_str_new(mrb_, + reinterpret_cast(&func_ptr), + sizeof(func_ptr)); + mrb_sym method_name_s = mrb_intern_cstr(mrb_, method_name); + mrb_value env[] = { + original_func_v, // 0: c function pointer + mrb_symbol_value(method_name_s), // 1: method name + }; + struct RProc* proc = mrb_proc_new_cfunc_with_env(mrb_, binder_func, 2, env); + mrb_field_write_barrier(mrb_, (RBasic *)proc, (RBasic *)proc->env); + struct RClass* klass = GetClass(module_name, class_name); + mrb_define_method_raw(mrb_, klass, method_name_s, proc); + } + + template + void bind_custom_method(const char* class_name, const char* method_name, Func func_ptr) { + bind_custom_method(NULL, class_name, method_name, func_ptr); + } + + //add convertable class pair + void add_convertable(const char* class_name_first, const char* class_name_second) + { + MrubyBindStatus::search(mrb_)->set_class_conversion(class_name_first, class_name_second, true); + MrubyBindStatus::search(mrb_)->set_class_conversion(class_name_second, class_name_first, true); + } + + mrb_state* get_mrb(){ + return mrb_; + } + mrb_value get_avoid_gc_table(){ + return avoid_gc_table_; + } + +private: + void Initialize(); + + // Returns mruby class under a module. + std::vector SplitModule(const char* module_name); + struct RClass* DefineModule(const char* module_name); + struct RClass* DefineClass(const char* module_name, const char* class_name); + struct RClass* GetClass(const char* class_name); + struct RClass* GetClass(const char* module_name, const char* class_name); + + // Utility for binding instance method. + void BindInstanceMethod(const char* class_name, const char* method_name, + mrb_value original_func_v, + mrb_value (*binder_func)(mrb_state*, mrb_value)); + void BindInstanceMethod(const char* module_name, + const char* class_name, const char* method_name, + mrb_value original_func_v, + mrb_value (*binder_func)(mrb_state*, mrb_value)); + + // Mimic mruby API. + // TODO: Send pull request to the official mruby repository. + void + mrb_define_class_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p); + + mrb_state* mrb_; + RClass* mod_; + mrb_value avoid_gc_table_; + int arena_index_; +}; + +MrubyRef load_string(mrb_state* mrb, std::string code); + +} // namespace mrubybind + +#endif diff --git a/codegen/mrubybind_types.1.h b/codegen/mrubybind_types.1.h new file mode 100644 index 0000000..3cbc40a --- /dev/null +++ b/codegen/mrubybind_types.1.h @@ -0,0 +1,586 @@ +// Describe type conversion between C type value and mruby value. + +#include "mruby/string.h" +#include "mruby/proc.h" +#include "mruby/array.h" +#include "mruby/hash.h" +#include "mruby/variable.h" +#include +#include +#include +#include +#include + +namespace mrubybind { + +extern const char* untouchable_table; +extern const char* untouchable_object; + +class MrubyArenaStore{ + mrb_state* mrb; + int ai; +public: + MrubyArenaStore(mrb_state* mrb) + { + this->mrb = mrb; + this->ai = mrb_gc_arena_save(mrb); + } + + ~MrubyArenaStore() + { + mrb_gc_arena_restore(mrb, ai); + } + +}; + +class MrubyBindStatus{ + +public: + + struct Data; + typedef std::shared_ptr Data_ptr; + typedef std::map Table; + + struct ObjectInfo + { + size_t ref_count; + size_t id; + + ObjectInfo() + { + this->ref_count = 0; + this->id = 0; + } + + ObjectInfo(size_t id) + { + this->ref_count = 1; + this->id = id; + } + }; + typedef std::map ObjectIdTable; + typedef std::vector FreeIdArray; + + static Table& get_living_table(){ + static Table table; + return table; + } + + struct Data{ + typedef std::map > ClassConvertableTable; + + + mrb_state* mrb; + mrb_value avoid_gc_table; + ClassConvertableTable class_convertable_table; + ObjectIdTable object_id_table; + FreeIdArray free_id_array; + + Data(){ + + } + ~Data(){ + + } + + mrb_state* get_mrb(){ + return mrb; + } + + mrb_value get_avoid_gc_table(){ + return avoid_gc_table; + } + + size_t new_id() + { + return mrb_ary_len(mrb, avoid_gc_table); + } + + ObjectIdTable& get_object_id_table() + { + return object_id_table; + } + + FreeIdArray& get_free_id_array() + { + return free_id_array; + } + + void set_class_conversion(const std::string& s, const std::string& d, bool c){ + class_convertable_table[s][d] = c; + } + + bool is_convertable(const std::string& s, const std::string& d) + { + auto fs = class_convertable_table.find(s); + if(fs != class_convertable_table.end()){ + auto fd = fs->second.find(d); + if(fd != fs->second.end()){ + return fd->second; + } + } + return false; + } + + }; + + MrubyBindStatus(){ + + } + + MrubyBindStatus(mrb_state* mrb, mrb_value avoid_gc_table){ + + Table& living_table = get_living_table(); + data = std::make_shared(); + data->mrb = mrb; + data->avoid_gc_table = avoid_gc_table; + living_table[mrb] = data; + } + + ~MrubyBindStatus(){ + + Table& living_table = MrubyBindStatus::get_living_table(); + living_table.erase(data->mrb); + data->mrb = NULL; + + } + + static bool is_living(mrb_state* mrb){ + Table& living_table = get_living_table(); + if(living_table.find(mrb) != living_table.end()){ + return living_table[mrb].get(); + } + return false; + } + + static Data_ptr search(mrb_state* mrb){ + Table& living_table = get_living_table(); + if(living_table.find(mrb) != living_table.end()){ + return living_table[mrb]; + } + return Data_ptr(NULL); + } + + + +private: + std::shared_ptr data; +}; + +template class Deleter{ + MrubyBindStatus::Data_ptr mrbsp; + mrb_value v_; +public: + Deleter() + { + + } + + Deleter(mrb_state* mrb, mrb_value v){ + if(!mrb_immediate_p(v)) + { + mrbsp = MrubyBindStatus::search(mrb); + mrb_value avoid_gc_table = mrbsp->get_avoid_gc_table(); + auto& object_id_table = mrbsp->get_object_id_table(); + auto& free_id_array = mrbsp->get_free_id_array(); + if(object_id_table.find(mrb_basic_ptr(v)) == object_id_table.end()) + { + size_t new_id; + if(!free_id_array.empty()) + { + new_id = free_id_array.back(); + free_id_array.pop_back(); + mrb_ary_set(mrb, avoid_gc_table, (mrb_int)new_id, v); + } + else + { + new_id = mrbsp->new_id(); + mrb_ary_push(mrb, avoid_gc_table, v); + } + object_id_table[mrb_basic_ptr(v)] = MrubyBindStatus::ObjectInfo(new_id); + } + else + { + object_id_table[mrb_basic_ptr(v)].ref_count++; + } + } + v_ = v; + + } + ~Deleter(){ + + } + mrb_state* get_mrb(){ + return mrbsp->mrb; + } + void operator()(T* p) const { + if(mrbsp.get()){ + mrb_state* mrb = mrbsp->get_mrb(); + if(mrb){ + mrb_value v = v_; + if(!mrb_immediate_p(v)) + { + mrb_value avoid_gc_table = mrbsp->get_avoid_gc_table(); + auto& object_id_table = mrbsp->get_object_id_table(); + auto& free_id_array = mrbsp->get_free_id_array(); + auto& oi = object_id_table[mrb_basic_ptr(v)]; + oi.ref_count--; + if(oi.ref_count <= 0) + { + mrb_ary_set(mrb, avoid_gc_table, (mrb_int)oi.id, mrb_nil_value()); + free_id_array.push_back(oi.id); + object_id_table.erase(mrb_basic_ptr(v)); + } + } + + + } + } + if(p){ + delete p; + } + } + +}; + +template using obj_ptr = std::shared_ptr; +//template using FuncPtr = std::shared_ptr >; + +template class FuncPtr{ + mrb_state* mrb; + std::shared_ptr > p; +public: + FuncPtr(){ + + } + templateFuncPtr(std::function* pt, D d) : p(pt, d){ + mrb = d.get_mrb(); + } + ~FuncPtr(){ + + } + const std::shared_ptr >& ref() const{ + return p; + } + bool is_living() const{ + return MrubyBindStatus::is_living(mrb); + } + std::function& func() const{ + if(!p.get()){ + throw std::runtime_error("empty function."); + } + return *p.get(); + } + operator bool() const { + if(!p.get()){ + return false; + } + return (bool)*p.get(); + } + void reset(){ + p.reset(); + } + template void reset(Y* y){ + p.reset(y); + } + template void reset(Y* y, D d){ + p.reset(y, d); + } + template void reset(Y* y, D d, A a){ + p.reset(y, d, a); + } +}; + +template Deleter set_avoid_gc(mrb_state* mrb, mrb_value v){ + return Deleter(mrb, v); +} + +template obj_ptr make_obj_ptr(Deleter d, T t){ + T* pt = new T(); + *pt = t; + return obj_ptr(pt, d); +} + +template FuncPtr make_FuncPtr(Deleter > d, std::function t){ + std::function* pt = new std::function(); + *pt = t; + return FuncPtr(pt, d); +} + +template +struct Type; + +class MrubyRef{ + mrb_state* mrb; + std::shared_ptr v; +public: + + MrubyRef(); + MrubyRef(mrb_state* mrb, const mrb_value& v); + ~MrubyRef(); + + bool is_living() const; + mrb_state* get_mrb() const; + mrb_value get_v()const; + bool empty() const; + bool test() const; + bool obj_equal(const MrubyRef& r) const; + std::string to_s() const; + int to_i() const; + float to_float() const; + double to_double() const; + + MrubyRef call(std::string name); + +#include "mrubybind_call_generated.h" + +}; + +//=========================================================================== +// C <-> mruby type converter. + +//template +//struct Type { + // Type name used for error message. + // static const char TYPE_NAME[]; + + // Returns whether the given mrb_value can be converted into type T. + //static int check(mrb_value v) = 0; + + // Converts mrb_value to type T value. + //static T get(mrb_value v) = 0; + + // Converts type T value to mrb_value. + //static mrb_value ret(mrb_state*, T i) = 0; +//}; + +// Fixnum +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_fixnum_p(v) || mrb_float_p(v); } + static int get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_fixnum_p(v) ? mrb_fixnum(v) : mrb_float(v); } + static mrb_value ret(mrb_state*, int i) { return mrb_fixnum_value(i); } +}; + +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_fixnum_p(v) || mrb_float_p(v); } + static unsigned int get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_fixnum_p(v) ? mrb_fixnum(v) : mrb_float(v); } + static mrb_value ret(mrb_state*, unsigned int i) { return mrb_fixnum_value(i); } +}; + +// float +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_float_p(v) || mrb_fixnum_p(v); } + static float get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_float_p(v) ? mrb_float(v) : mrb_fixnum(v); } + static mrb_value ret(mrb_state* mrb, float f) { return mrb_float_value(mrb, f); } +}; + +// double +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_float_p(v) || mrb_fixnum_p(v); } + static double get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_float_p(v) ? mrb_float(v) : mrb_fixnum(v); } + static mrb_value ret(mrb_state* mrb, double f) { return mrb_float_value(mrb, f); } +}; + +// String +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_string_p(v); } + static const char* get(mrb_state* mrb, mrb_value v) { (void)mrb; return RSTRING_PTR(v); } + static mrb_value ret(mrb_state* mrb, const char* s) { return mrb_str_new_cstr(mrb, s); } +}; + +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_string_p(v); } + static const std::string get(mrb_state* mrb, mrb_value v) { (void)mrb; return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } + static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } +}; + +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_string_p(v); } + static const std::string get(mrb_state* mrb, mrb_value v) { (void)mrb; return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } + static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } +}; + +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_string_p(v); } + static const std::string get(mrb_state* mrb, mrb_value v) { (void)mrb; return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } + static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } +}; + +// Boolean +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value /*v*/) { return 1; } + static bool get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_test(v); } + static mrb_value ret(mrb_state* /*mrb*/, bool b) { return b ? mrb_true_value() : mrb_false_value(); } +}; + +// Raw pointer +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_cptr_p(v); } + static void* get(mrb_state*, mrb_value v) { return mrb_cptr(v); } + static mrb_value ret(mrb_state* mrb, void* p) { return mrb_cptr_value(mrb, p); } +}; + +// Function +struct TypeFuncBase{ + static const char TYPE_NAME[]; +}; + +template +struct Type > :public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](){ + MrubyArenaStore mas(mrb); + return Type::get(mrb, mrb_yield(mrb, v, mrb_nil_value())); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +template<> +struct Type > :public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](){ + MrubyArenaStore mas(mrb); + mrb_yield(mrb, v, mrb_nil_value()); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// mruby value +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value) { return 1; } + static MrubyRef get(mrb_state* mrb, mrb_value v) { (void)mrb; return MrubyRef(mrb, v); } + static mrb_value ret(mrb_state*, MrubyRef r) { return r.get_v(); } +}; + + +#include "mrubybind_types_generated.h" + +//=========================================================================== +// Binder + +// Template class for Binder. +// Binder template class is specialized with type. +template +struct Binder { + // Template specialization. + //static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) = 0; +}; + +// Template class for Binder. +// Binder template class is specialized with type. +template +struct ClassBinder { + static struct mrb_data_type type_info; + static void dtor(mrb_state*, void* p) { + C* instance = static_cast(p); + delete instance; + } + + // Template specialization. + //static void ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { +}; +template +mrb_data_type ClassBinder::type_info = { "???", dtor }; + +template +struct CustomClassBinder { + // Template specialization. + //static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) = 0; +}; + +// Other Class +struct TypeClassBase{ + static const char TYPE_NAME[]; +}; + +template struct Type :public TypeClassBase { + static std::string class_name; + static int check(mrb_state* mrb, mrb_value v) { + return mrb_type(v) == MRB_TT_DATA && + MrubyBindStatus::search(mrb)->is_convertable(mrb_obj_classname(mrb, v), class_name); + } + static T& get(mrb_state* mrb, mrb_value v) { + (void)mrb; return *(T*)DATA_PTR(v); + } + static mrb_value ret(mrb_state* mrb, T t) { + RClass* cls; + mrb_value v; + cls = mrb_class_get(mrb, class_name.c_str()); + v = mrb_class_new_instance(mrb, 0, NULL, cls); + DATA_TYPE(v) = &ClassBinder::type_info; + T* nt = new T(); + *nt = t; + DATA_PTR(v) = nt; + return v; + } +}; + +template std::string Type::class_name = ""; + +template struct Type :public TypeClassBase { + static std::string class_name; + static int check(mrb_state* mrb, mrb_value v) { + return mrb_type(v) == MRB_TT_DATA && + MrubyBindStatus::search(mrb)->is_convertable(mrb_obj_classname(mrb, v), class_name); + } + static T get(mrb_state* mrb, mrb_value v) { + (void)mrb; return *(T*)DATA_PTR(v); + } + static mrb_value ret(mrb_state* mrb, T t) { + RClass* cls; + mrb_value v; + cls = mrb_class_get(mrb, class_name.c_str()); + v = mrb_class_new_instance(mrb, 0, NULL, cls); + DATA_TYPE(v) = &ClassBinder::type_info; + T* nt = new T(); + *nt = t; + DATA_PTR(v) = nt; + return v; + } +}; + +template std::string Type::class_name = ""; + +// +mrb_value raise(mrb_state *mrb, int parameter_index, + const char* required_type_name, mrb_value value); +mrb_value raisenarg(mrb_state *mrb, mrb_value func_name, int narg, int nparam); + +// Includes generated template specialization. +//#include "mrubybind.inc" diff --git a/codegen/mrubybind_types.3.h b/codegen/mrubybind_types.3.h new file mode 100644 index 0000000..d578b2b --- /dev/null +++ b/codegen/mrubybind_types.3.h @@ -0,0 +1,2 @@ + +} // namespace mrubybind diff --git a/examples/Makefile b/examples/Makefile index ecdc300..24fba96 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -7,7 +7,6 @@ all: a.out clean: rm -rf *.o a.out -a.out: main.cc ../mrubybind.cc ../mrubybind.h ../mrubybind_types.h ../mrubybind.inc ../mrubybind.dat - g++ -o a.out main.cc ../mrubybind.cc $(INC) $(LIB) +a.out: main.cc ../mrubybind.cc ../mrubybind.h ../mrubybind.inc ../mrubybind.dat + g++ -g -std=c++11 -o a.out -Wall -Wextra main.cc ../mrubybind.cc $(INC) $(LIB) -# diff --git a/examples/main.cc b/examples/main.cc index cb5919a..c15e72f 100644 --- a/examples/main.cc +++ b/examples/main.cc @@ -3,92 +3,400 @@ #include "mrubybind.h" #include +#include +#include +#include using namespace std; -void hoge() { - cout << "hoge called" << endl; -} - -void fuga(const char* str) { - cout << "fuga called: " << str << endl; -} - -std::string piyo(const std::string& s) { - return s + s; -} +//============================================================================= +// Simple usage for binding function. int square(int x) { return x * x; } -double add(double x, double y) { - return x + y; +string emphasize(const char* str) { + return "* " + string(str) + " *"; } -void test(bool t) { - cout << t << endl; +void BindFunctionTest(mrb_state* mrb) { + { + mrubybind::MrubyBind b(mrb); + b.bind("square", square); + b.bind("emphasize", emphasize); + } + + mrubybind::load_string(mrb, + "puts square(1111)\n" + "puts emphasize('Hello, mruby!')\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + } } +//============================================================================= +// Simple usage for binding C++ class. -class Hoge { +class Foo { public: - Hoge(int x) : x_(x) { - cout << "Hoge::ctor(" << x << ")" << endl; + Foo(int x) : x_(x) { + cout << "Foo::ctor(" << x << "), " << this << endl; } - virtual ~Hoge() { - cout << "Hoge::dtor()" << endl; + virtual ~Foo() { + cout << "Foo::dtor(), " << this << endl; } - int hoge(int y) { + int bar(int y) { return x_ + y; } + static int baz(int z) { + return z * z; + } private: int x_; }; -void* new_hoge(int x) { - return (void*)new Hoge(x); +Foo* new_foo(int x) { + return new Foo(x); } +void BindClassTest(mrb_state* mrb) { + { + mrubybind::MrubyBind b(mrb); + b.bind_class("Foo", new_foo); + b.bind_instance_method("Foo", "bar", &Foo::bar); + b.bind_static_method("Foo", "baz", &Foo::baz); + } + mrubybind::load_string(mrb, + "foo = Foo.new(123)\n" + "p foo\n" + "p foo.bar(567)\n" + "foo = nil\n" + "p Foo.baz(9999)" + ); -int main() { - mrb_state* mrb = mrb_open(); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + } +} +//============================================================================= +// Simple usage for binding function under some module. + +void modfunc(int v) { + printf("modfunc called: %d\n", v); +} + +void UseModuleTest(mrb_state* mrb) { { - mrubybind::MrubyBind b(mrb); - b.bind("hoge", hoge); - b.bind("fuga", fuga); - b.bind("piyo", piyo); - b.bind("square", square); - b.bind("add", add); - b.bind("test", test); - } - mrb_load_string(mrb, - "hoge()\n" - "fuga('piyo')\n" - "p piyo('abc')\n" - "p test('')\n" - "p square(1111)\n" - "p add(1.23, 9.87)\n" + mrubybind::MrubyArenaStore mas(mrb); + RClass* mod = mrb_define_module(mrb, "Mod"); + mrubybind::MrubyBind b(mrb, mod); + b.bind("modfunc", modfunc); + b.bind_const("FOO_VALUE", 1234); + } + + mrubybind::load_string(mrb, + "Mod.modfunc(Mod::FOO_VALUE)\n" ); if (mrb->exc) { mrb_p(mrb, mrb_obj_value(mrb->exc)); } +} + +//============================================================================= +// + +std::string call_block(mrubybind::FuncPtr f) { + if(f) + { + cout << "pre f\n"; + f.func()(); + cout << "post f\n"; + } + return "call_block called\n"; +} + +std::string call_block_a1(mrubybind::FuncPtr f) { + if(f) + { + f.func()(23); + } + return "call_block_a1 called\n"; +} + +std::string call_block_a2(mrubybind::FuncPtr f) { + if(f) + { + f.func()(23, "string"); + } + return "call_block_a2 called\n"; +} + +std::string call_block_a1_int(mrubybind::FuncPtr f) { + std::stringstream s; + s << "call_block_a1_int return this ->" << f.func()(23); + return s.str(); +} + +mrubybind::FuncPtr old_f; + +void set_old_f(mrubybind::FuncPtr f) { + std::cout << "set_old_f() pre" << std::endl; + old_f = f; + std::cout << "set_old_f() post" << std::endl; +} + +void call_old_f() { + std::cout << "call_old_f() pre" << std::endl; + old_f.func()(); + std::cout << "call_old_f() post" << std::endl; +} + + +class Callbacker +{ + int a; +public: + Callbacker() + { + a = 5; + } + + int func_test(mrubybind::FuncPtr f) + { + f.func()(a); + return a; + } + + std::string func_a2_string(mrubybind::FuncPtr f) { + return f.func()(48, "str"); + } +}; + +Callbacker* new_callbacker() +{ + return new Callbacker(); +} + +void CallbackFunctionTest(mrb_state* mrb) { { mrubybind::MrubyBind b(mrb); - b.define_class("Hoge", new_hoge); - b.define_class_method("Hoge", "hoge", &Hoge::hoge); + b.bind("call_block", call_block); + b.bind("call_block_a1", call_block_a1); + b.bind("call_block_a2", call_block_a2); + b.bind("call_block_a1_int", call_block_a1_int); + b.bind("set_old_f", set_old_f); + b.bind("call_old_f", call_old_f); + + b.bind_class("Callbacker", new_callbacker); + b.bind_instance_method("Callbacker", "func_test", &Callbacker::func_test); + b.bind_instance_method("Callbacker", "func_a2_string", &Callbacker::func_a2_string); } - mrb_load_string(mrb, - "h = Hoge.new(111)\n" - "p h.hoge(567)\n" - ); + mrubybind::load_string(mrb, + "v = call_block do\n" + " puts \"?? called\n\"" + "end\n" + "puts v\n" + "puts call_block_a1 { |a0|\n" + " puts \"a0 = #{a0}\"\n" + "}\n" + "puts call_block_a2 { |a0, a1|\n" + " puts \"a0 = #{a0}, a1 = #{a1}\"\n" + "}\n" + "puts call_block_a1_int { |a0|\n" + " puts \"a0 = #{a0}\"\n" + "}\n" + "puts \"Callbacker.new.func_test \" + Callbacker.new.func_test {|a0|\n" + " puts \"class a0 = #{a0}\"\n" + "}.to_s\n" + "puts \"Callbacker.new.func_a2_string \" + Callbacker.new.func_a2_string {|a0, a1|\n" + " puts \"class a0 = #{a0}, a1 = #{a1}\"\n" + " \"cat #{a0} #{a1}\"\n" + "}.to_s\n" + "set_old_f do puts \"call old_f\"; end" + ); if (mrb->exc) { mrb_p(mrb, mrb_obj_value(mrb->exc)); } + mrubybind::load_string(mrb, + "GC.start\n" + ); + mrubybind::load_string(mrb, + "puts \"later...\"\n" + "call_old_f\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + } +} + +//============================================================================= +// + +class ClassValue{ +public: + int a; + + ClassValue(){ + std::cout << "ClassValue construct.\n"; + std::cout.flush(); + a = 7; + } + + ~ClassValue(){ + std::cout << "ClassValue destruct.\n"; + std::cout.flush(); + } + + void decriment(){ + a--; + } +}; + +std::shared_ptr create_class_value() +{ + return std::shared_ptr(new ClassValue()); + //return ClassValue(); +} + +void class_value_increment(std::shared_ptr cv) +{ + cv->a++; +} + +int class_value_get_a(std::shared_ptr cv) +{ + return cv->a; +} + +void class_value_decriment(std::shared_ptr cv) +{ + cv->decriment(); +} + +void class_value_add(std::shared_ptr cv, int n) +{ + cv->a += n; +} + +std::weak_ptr convert_to_weak_class_value(std::shared_ptr cv){ + return cv; +} + +int weak_class_value_get_a(std::weak_ptr cv) +{ + if(auto ptr = cv.lock()){ + return ptr->a; + } + return 0; +} + +void ClassPointerTest(mrb_state* mrb){ + + { + mrubybind::MrubyBind b(mrb); + b.bind("create_class_value", create_class_value); + b.bind_class >("ClassValue"); + b.bind_class >("WeakClassValue"); + b.bind("class_value_increment", class_value_increment); + b.bind("class_value_get_a", class_value_get_a); + b.bind_custom_method(NULL, "ClassValue", "decriment", class_value_decriment); + b.bind_custom_method(NULL, "ClassValue", "add", class_value_add); + b.bind("convert_to_weak_class_value", convert_to_weak_class_value); + b.bind("weak_class_value_get_a", weak_class_value_get_a); + } + + mrubybind::load_string(mrb, + "puts \"start ClassPointerTest\"\n" + "cv = create_class_value\n" + "puts \"cv -> #{class_value_get_a(cv)}\"\n" + "class_value_increment(cv)\n" + "puts \"cv -> #{class_value_get_a cv}\"\n" + "cv.decriment\n" + "puts \"cv -> #{class_value_get_a cv}\"\n" + "cv.add 4\n" + "puts \"cv -> #{class_value_get_a cv}\"\n" + "wk = convert_to_weak_class_value cv\n" + "puts \"wk->#{weak_class_value_get_a wk}\"\n" + "cv = nil\n" + "puts \"GC\"\n" + "GC.start\n" + "puts \"wk->#{weak_class_value_get_a wk}\"\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + } +} + +//============================================================================= +// + +mrubybind::MrubyRef mruby_ref; +mrubybind::MrubyRef mruby_ref_a, mruby_ref_b; + +void set_mruby_ref(mrubybind::MrubyRef r){ + mruby_ref = r; +} + +void set_mruby_ref_pair(mrubybind::MrubyRef a, mrubybind::MrubyRef b){ + mruby_ref_a = a; + mruby_ref_b = b; +} + +void MrubyRefTest(mrb_state* mrb){ + + { + mrubybind::MrubyBind b(mrb); + b.bind("set_mruby_ref", set_mruby_ref); + b.bind("set_mruby_ref_pair", set_mruby_ref_pair); + + } + + mrubybind::load_string(mrb, + "set_mruby_ref \"3test\"\n" + "s = \"aaa\"\n" + "set_mruby_ref_pair s, s\n" + "set_mruby_ref_pair :s, :s\n" + ); + // + std::cout << "mruby_ref = " << mruby_ref.to_s() << std::endl; + std::cout << "mruby_ref = " << mruby_ref.to_i() << std::endl; + std::cout << "mruby_ref = " << mruby_ref.call("gsub", "te", "toa").to_s() << std::endl; + std::cout << ":a == :a = " << mruby_ref_a.obj_equal(mruby_ref_b) << std::endl; + std::cout << "arena_index = " << mrb_gc_arena_save(mrb) << std::endl; + + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + } +} + + +//============================================================================= +int main() { + mrb_state* mrb = mrb_open(); + + try{ + BindFunctionTest(mrb); + BindClassTest(mrb); + UseModuleTest(mrb); + CallbackFunctionTest(mrb); + ClassPointerTest(mrb); + MrubyRefTest(mrb); + } + catch(std::runtime_error e){ + std::cout << "std::runtime_error -> " << e.what() << std::endl; + } + catch(...){ + std::cout << "unknown error!" << std::endl; + std::cout.flush(); + throw; + } + mrb_close(mrb); return 0; diff --git a/mrubybind.cc b/mrubybind.cc index 3915ed5..883b6ec 100644 --- a/mrubybind.cc +++ b/mrubybind.cc @@ -1,54 +1,349 @@ +// Do not modify this file directly, this is generated #include "mrubybind.h" -#include -#include -#include -#include +#include "mruby/compile.h" +#include "mruby/dump.h" +#include "mruby/proc.h" +#include "mruby/string.h" +#include "mruby/variable.h" +#include namespace mrubybind { -static -#include "mrubybind.dat" - -static mrb_value call_cfunc(mrb_state *mrb, mrb_value self) { - mrb_value binder; - mrb_value p; - mrb_value* args; - int narg; - mrb_get_args(mrb, "oo*", &binder, &p, &args, &narg); - typedef mrb_value (*BindFunc)(mrb_state*, void*, mrb_value*, int); - BindFunc binderp = (BindFunc)mrb_voidp(binder); - return binderp(mrb, mrb_voidp(p), args, narg); -} - -static mrb_value call_cmethod(mrb_state *mrb, mrb_value self) { - mrb_value binder; - mrb_value o; - mrb_value p; - mrb_value* args; - int narg; - mrb_get_args(mrb, "ooo*", &binder, &o, &p, &args, &narg); - typedef mrb_value (*BindFunc)(mrb_state*, void*, void*, mrb_value*, int); - BindFunc binderp = (BindFunc)mrb_voidp(binder); - return binderp(mrb, mrb_voidp(o), RSTRING_PTR(p), args, narg); -} - -MrubyBind::MrubyBind(mrb_state* mrb) { - this->mrb = mrb; - mrb_sym sym_mrubybind = mrb_intern(mrb, "MrubyBind"); - if (mrb_const_defined(mrb, mrb_obj_value(mrb->kernel_module), sym_mrubybind)) { - this->mod_mrubybind = mrb_const_get(mrb, mrb_obj_value(mrb->kernel_module), sym_mrubybind); +//#include "mrubybind.dat" + + +const char Type::TYPE_NAME[] = "Fixnum"; +const char Type::TYPE_NAME[] = "Fixnum"; +const char Type::TYPE_NAME[] = "Float"; +const char Type::TYPE_NAME[] = "Float"; +const char Type::TYPE_NAME[] = "String"; +const char Type::TYPE_NAME[] = "String"; +const char Type::TYPE_NAME[] = "String"; +const char Type::TYPE_NAME[] = "String"; +const char Type::TYPE_NAME[] = "Bool"; +const char Type::TYPE_NAME[] = "Voidp"; +const char Type::TYPE_NAME[] = "MrubyRef"; +const char TypeFuncBase::TYPE_NAME[] = "Func"; +const char TypeClassBase::TYPE_NAME[] = "CppClass"; + +const char* untouchable_table = "__ untouchable table __"; +const char* untouchable_object = "__ untouchable object __"; +const char* untouchable_last_exception = "__ untouchable last exception __"; + +mrb_value raise(mrb_state *mrb, int parameter_index, + const char* required_type_name, mrb_value value) { + const char * argument_class_name = mrb_obj_classname(mrb, value); + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S, argument %S(%S)", + mrb_str_new_cstr(mrb, argument_class_name), + mrb_str_new_cstr(mrb, required_type_name), + mrb_fixnum_value(parameter_index + 1), value); + return mrb_nil_value(); +} + +mrb_value raisenarg(mrb_state *mrb, mrb_value func_name, int narg, int nparam) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S': wrong number of arguments (%S for %S)", + func_name, + mrb_fixnum_value(narg), + mrb_fixnum_value(nparam)); + return mrb_nil_value(); +} + + +void +MrubyBind::mrb_define_class_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p) +{ + mrb_define_class_method(mrb, c, mrb_sym2name(mrb, mid), NULL, MRB_ARGS_ANY()); // Dummy registration. + mrb_define_method_raw(mrb, ((RObject*)c)->c, mid, p); +} + +MrubyBind::MrubyBind(mrb_state* mrb) : mrb_(mrb), mod_(mrb_->kernel_module) { + Initialize(); +} + +MrubyBind::MrubyBind(mrb_state* mrb, RClass* mod) : mrb_(mrb), mod_(mod) { + Initialize(); +} + +MrubyBind::~MrubyBind() { + mrb_gc_arena_restore(mrb_, arena_index_); +} + +void MrubyBind::Initialize() { + arena_index_ = mrb_gc_arena_save(mrb_); + mrb_sym sym_mrubybind = mrb_intern_cstr(mrb_, "MrubyBind"); + RClass* mrubybind = mrb_define_module(mrb_, "MrubyBind"); + if (mrb_const_defined(mrb_, mrb_obj_value(mrb_->kernel_module), + sym_mrubybind)) { + avoid_gc_table_ = mrb_obj_iv_get(mrb_, (RObject*)mrubybind, + mrb_intern_cstr(mrb_, untouchable_table)); } else { - RClass* mrubybind = mrb_define_module(mrb, "MrubyBind"); - this->mod_mrubybind = mrb_obj_value(mrubybind); - mrb_define_module_function(mrb, mrubybind, "call_cfunc", call_cfunc, - ARGS_REQ(2) | ARGS_REST()); - mrb_define_module_function(mrb, mrubybind, "call_cmethod", call_cmethod, - ARGS_REQ(3) | ARGS_REST()); - int n = mrb_read_irep(mrb, binder); - if (n >= 0) { - mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); + mrb_const_set(mrb_, mrb_obj_value(mrb_->kernel_module), sym_mrubybind, mrb_obj_value(mrubybind)); + + { + avoid_gc_table_ = mrb_ary_new(mrb_); + mrb_obj_iv_set(mrb_, (RObject*)mrubybind, + mrb_intern_cstr(mrb_, untouchable_table), avoid_gc_table_); + std::shared_ptr mrbs = std::make_shared(mrb_, avoid_gc_table_); + mrubybind::MrubyBind b(mrb_); + b.bind_class >("MrubyBind", "MrubyBindStatusPtr"); + mrb_value msbpv = Type >::ret(mrb_, mrbs); + mrb_obj_iv_set(mrb_, (RObject*)mrubybind, + mrb_intern_cstr(mrb_, untouchable_object), msbpv); } } } +std::vector MrubyBind::SplitModule(const char* module_name) +{ + std::vector splited; + if(!module_name){ + return splited; + } + std::string str(module_name); + std::string d("::"); + size_t c = 0, f, dsz = d.size(); + while((f = str.find(d, c)) != std::string::npos){ + splited.push_back(str.substr(c, f - c)); + c = f + dsz; + } + splited.push_back(str.substr(c, str.size() - c)); + return splited; +} + +struct RClass* MrubyBind::DefineModule(const char* module_name) +{ + std::vector modules = SplitModule(module_name); + struct RClass* last_module = nullptr; + for(size_t i = 0 ; i < modules.size() ; i++){ + auto m = modules[i]; + if(i == 0){ + if(mrb_const_defined_at(mrb_, mrb_obj_value(mrb_->object_class), mrb_intern_cstr(mrb_, m.c_str()))){ + mrb_value mdl = mrb_const_get(mrb_, mrb_obj_value(mrb_->object_class), mrb_intern_cstr(mrb_, m.c_str())); + last_module = mrb_class_ptr(mdl); + } + else { + last_module = mrb_define_module(mrb_, m.c_str()); + } + } + else{ + if(mrb_const_defined_at(mrb_, mrb_obj_value(mrb_->object_class), mrb_intern_cstr(mrb_, m.c_str()))){ + mrb_value mdl = mrb_const_get(mrb_, mrb_obj_value(last_module), mrb_intern_cstr(mrb_, m.c_str())); + last_module = mrb_class_ptr(mdl); + } + else { + last_module = mrb_define_module_under(mrb_, last_module, m.c_str()); + } + } + } + return last_module; +} + +struct RClass* MrubyBind::DefineClass(const char* module_name, const char* class_name) +{ + struct RClass * tc; + mrb_value mod = mrb_obj_value(mod_); + std::string name; + if(module_name){ + name = module_name; + name += "::"; + name += class_name; + tc = mrb_define_class(mrb_, name.c_str(), mrb_->object_class); + struct RClass * mdp = DefineModule(module_name); + mod = mrb_obj_value(mdp); + mrb_define_const(mrb_, mdp, class_name, mrb_obj_value(tc)); + } + else + { + name = class_name; + tc = mrb_define_class(mrb_, class_name, mrb_->object_class); + } + return tc; +} + +struct RClass* MrubyBind::GetClass(const char* class_name) { + mrb_value mod = mrb_obj_value(mod_); + mrb_value klass_v = mrb_const_get(mrb_, mod, mrb_intern_cstr(mrb_, class_name)); + return mrb_class_ptr(klass_v); +} + +struct RClass* MrubyBind::GetClass(const char* module_name, const char* class_name) { + mrb_value mod = mrb_obj_value(mod_); + if(module_name){ + mod = mrb_obj_value(DefineModule(module_name)); + } + mrb_value klass_v = mrb_const_get(mrb_, mod, mrb_intern_cstr(mrb_, class_name)); + return mrb_class_ptr(klass_v); +} + +void MrubyBind::BindInstanceMethod( + const char* class_name, const char* method_name, + mrb_value original_func_v, + mrb_value (*binder_func)(mrb_state*, mrb_value)) { + BindInstanceMethod(NULL, + class_name, method_name, + original_func_v, + binder_func); +} + +void MrubyBind::BindInstanceMethod(const char* module_name, + const char* class_name, const char* method_name, + mrb_value original_func_v, + mrb_value (*binder_func)(mrb_state*, mrb_value)) +{ + mrb_sym method_name_s = mrb_intern_cstr(mrb_, method_name); + mrb_value env[] = { + original_func_v, // 0: c function pointer + mrb_symbol_value(method_name_s), // 1: method name + }; + struct RProc* proc = mrb_proc_new_cfunc_with_env(mrb_, binder_func, 2, env); + struct RClass* klass = GetClass(module_name, class_name); + mrb_define_method_raw(mrb_, klass, method_name_s, proc); +} + +MrubyRef load_string(mrb_state* mrb, std::string code) +{ + mrubybind::MrubyArenaStore mas(mrb); + + RClass* mrubybind = mrb_define_module(mrb, "MrubyBind"); + mrb->exc = NULL; + mrb_value r = mrb_load_string(mrb, + code.c_str()); + if(mrb->exc){ + mrb_obj_iv_set(mrb, (RObject*)mrubybind, + mrb_intern_cstr(mrb, untouchable_last_exception), mrb_obj_value(mrb->exc)); + r = mrb_nil_value(); + } + else{ + mrb_obj_iv_set(mrb, (RObject*)mrubybind, + mrb_intern_cstr(mrb, untouchable_last_exception), mrb_nil_value()); + } + + return MrubyRef(mrb, r); +} + +MrubyRef::MrubyRef(){ + +} + +MrubyRef::MrubyRef(mrb_state* mrb, const mrb_value& v){ + this->mrb = mrb; + mrb_value* p = new mrb_value(); + *p = v; + this->v = std::shared_ptr(p, set_avoid_gc(mrb, v)); +} + +MrubyRef::~MrubyRef(){ + +} + +bool MrubyRef::is_living() const{ + return MrubyBindStatus::is_living(mrb); +} + +mrb_state* MrubyRef::get_mrb() const{ + return this->mrb; +} + +mrb_value MrubyRef::get_v() const{ + if(v.get()){ + return *(this->v.get()); + } + return mrb_nil_value(); +} + +bool MrubyRef::empty() const{ + if(!v.get()){ + return true; + } + return false; +} + +bool MrubyRef::test() const{ + if(v.get()){ + mrb_value v = *(this->v.get()); + return mrb_test(v); + } + return false; +} + +bool MrubyRef::obj_equal(const MrubyRef& r) const{ + if(!empty() && !r.empty()){ + return mrb_obj_equal(mrb, get_v(), r.get_v()); + } + else{ + return empty() == r.empty(); + } +} + +std::string MrubyRef::to_s() const{ + if(v.get()){ + MrubyArenaStore mas(mrb); + mrb_value v = *(this->v.get()); + if(mrb_string_p(v)){ + return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); + } + else{ + v = mrb_funcall(mrb, v, "to_s", 0); + return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); + } + } + else{ + return ""; + } +} + +int MrubyRef::to_i() const{ + if(v.get()){ + mrb_value v = *(this->v.get()); + if(mrb_fixnum_p(v)){ + return mrb_fixnum(v); + } + else{ + v = mrb_funcall(mrb, v, "to_i", 0); + return mrb_fixnum(v); + } + } + else{ + return 0; + } +} + +float MrubyRef::to_float() const{ + if(v.get()){ + mrb_value v = *(this->v.get()); + if(mrb_float_p(v)){ + return mrb_float(v); + } + else{ + v = mrb_funcall(mrb, v, "to_f", 0); + return mrb_float(v); + } + } + else{ + return 0.0f; + } +} + +double MrubyRef::to_double() const{ + if(v.get()){ + mrb_value v = *(this->v.get()); + if(mrb_float_p(v)){ + return mrb_float(v); + } + else{ + v = mrb_funcall(mrb, v, "to_f", 0); + return (double)mrb_float(v); + } + } + else{ + return 0.0; + } +} + +MrubyRef MrubyRef::call(std::string name){ + MrubyArenaStore mas(mrb); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 0)); +} + + } // namespace mrubybind diff --git a/mrubybind.dat b/mrubybind.dat index ed7fe61..f86353a 100644 --- a/mrubybind.dat +++ b/mrubybind.dat @@ -1,58 +1,162 @@ +#include const uint8_t binder[] = { -0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x31,0xde,0x82,0x00,0x00,0x03,0x76,0x4d,0x41, -0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x03,0x58,0x30,0x30, -0x30,0x30,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x2f,0x00,0x01,0x00,0x02,0x00,0x00, -0x00,0x04,0x00,0x80,0x00,0x05,0x00,0x80,0x00,0x44,0x00,0x80,0x00,0xc5,0x00,0x00, -0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x09,0x4d,0x72,0x75,0x62, -0x79,0x42,0x69,0x6e,0x64,0x00,0x00,0x00,0x8b,0x00,0x01,0x00,0x02,0x00,0x00,0x00, -0x0e,0x00,0x80,0x00,0x91,0x00,0x80,0x40,0x47,0x01,0x00,0x02,0xc0,0x00,0x80,0x00, -0x46,0x00,0x80,0x00,0x91,0x00,0x80,0x40,0x47,0x01,0x00,0x06,0xc0,0x00,0x80,0x80, -0x46,0x00,0x80,0x00,0x91,0x00,0x80,0x40,0x47,0x01,0x00,0x0c,0xc0,0x00,0x80,0xc0, -0x46,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x04,0x00,0x0f,0x64,0x65,0x66,0x69,0x6e,0x65,0x5f,0x66,0x75,0x6e,0x63,0x74,0x69, -0x6f,0x6e,0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42,0x69,0x6e,0x64,0x00,0x0c,0x63, -0x72,0x65,0x61,0x74,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x00,0x13,0x64,0x65,0x66, -0x69,0x6e,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64, -0x00,0x00,0x00,0x4d,0x00,0x05,0x00,0x09,0x00,0x00,0x00,0x07,0x06,0x00,0x00,0x26, -0x02,0x80,0x00,0x11,0x03,0x00,0x01,0x04,0x03,0x80,0x80,0x01,0x04,0x00,0x03,0x40, -0x02,0x80,0x41,0x21,0x02,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, -0x00,0x06,0x4b,0x65,0x72,0x6e,0x65,0x6c,0x00,0x04,0x73,0x65,0x6e,0x64,0x00,0x0d, -0x64,0x65,0x66,0x69,0x6e,0x65,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64,0x00,0x00,0x00, -0x4f,0x00,0x03,0x00,0x06,0x00,0x00,0x00,0x09,0x00,0x08,0x00,0x26,0x01,0x80,0x00, -0x11,0x02,0x00,0x40,0x15,0x02,0x80,0xc0,0x15,0x02,0x01,0x01,0x37,0x02,0x80,0x40, -0x01,0x02,0x01,0x40,0x38,0x01,0x80,0x7f,0xa0,0x01,0x80,0x00,0x29,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x02,0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42,0x69,0x6e,0x64, -0x00,0x0a,0x63,0x61,0x6c,0x6c,0x5f,0x63,0x66,0x75,0x6e,0x63,0x00,0x00,0x00,0x6b, -0x00,0x06,0x00,0x09,0x00,0x00,0x00,0x0b,0x06,0x00,0x00,0x26,0x03,0x00,0x00,0x11, -0x03,0x80,0x80,0x01,0x04,0x00,0x01,0x11,0x04,0x00,0xc0,0x20,0x03,0x00,0x41,0x20, -0x02,0x81,0x80,0x01,0x03,0x01,0x40,0x01,0x03,0x80,0x03,0x40,0x03,0x01,0x00,0x21, -0x03,0x00,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x06,0x4b,0x65, -0x72,0x6e,0x65,0x6c,0x00,0x09,0x63,0x6f,0x6e,0x73,0x74,0x5f,0x73,0x65,0x74,0x00, -0x05,0x43,0x6c,0x61,0x73,0x73,0x00,0x03,0x6e,0x65,0x77,0x00,0x0a,0x63,0x6c,0x61, -0x73,0x73,0x5f,0x65,0x76,0x61,0x6c,0x00,0x00,0x00,0x43,0x00,0x01,0x00,0x04,0x00, -0x00,0x00,0x05,0x00,0x80,0x00,0x06,0x01,0x00,0x00,0x84,0x01,0x80,0x03,0x40,0x00, -0x80,0x00,0xa1,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, -0x0d,0x64,0x65,0x66,0x69,0x6e,0x65,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64,0x00,0x0a, -0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x69,0x7a,0x65,0x00,0x00,0x00,0x5e,0x00,0x03, -0x00,0x06,0x00,0x00,0x00,0x0a,0x00,0x08,0x00,0x26,0x01,0x80,0x00,0x11,0x02,0x00, -0x40,0x95,0x02,0x80,0xc0,0x95,0x02,0x01,0x01,0x37,0x02,0x80,0x40,0x01,0x02,0x01, -0x40,0x38,0x01,0x80,0x7f,0xa0,0x01,0x80,0x01,0x0e,0x01,0x80,0x00,0x29,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42,0x69,0x6e, -0x64,0x00,0x0a,0x63,0x61,0x6c,0x6c,0x5f,0x63,0x66,0x75,0x6e,0x63,0x00,0x09,0x40, -0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x00,0x00,0x00,0x4f,0x00,0x06,0x00,0x08, -0x00,0x00,0x00,0x07,0x08,0x00,0x00,0x26,0x03,0x00,0x00,0x11,0x03,0x80,0x80,0x01, -0x03,0x00,0x40,0xa0,0x03,0x80,0x03,0x40,0x03,0x00,0x80,0x21,0x03,0x00,0x00,0x29, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x06,0x4b,0x65,0x72,0x6e,0x65,0x6c, -0x00,0x09,0x63,0x6f,0x6e,0x73,0x74,0x5f,0x67,0x65,0x74,0x00,0x0a,0x63,0x6c,0x61, -0x73,0x73,0x5f,0x65,0x76,0x61,0x6c,0x00,0x00,0x00,0x37,0x00,0x01,0x00,0x04,0x00, -0x00,0x00,0x05,0x00,0x80,0x00,0x06,0x01,0x00,0xc0,0x15,0x01,0x80,0x03,0x40,0x00, +0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x32,0x7e,0x5e,0x00,0x00,0x09,0xe1,0x4d,0x41, +0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x09,0xc3,0x30,0x30, +0x30,0x30,0x00,0x00,0x00,0x32,0x00,0x01,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x04, +0x00,0x80,0x00,0x05,0x00,0x80,0x00,0x44,0x00,0x80,0x00,0x45,0x00,0x00,0x00,0x4a, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42, +0x69,0x6e,0x64,0x00,0x00,0x00,0x00,0xda,0x00,0x01,0x00,0x02,0x00,0x05,0x00,0x00, +0x00,0x16,0x00,0x80,0x00,0x91,0x00,0x80,0x40,0x47,0x01,0x00,0x00,0xc0,0x00,0x80, +0x00,0x46,0x00,0x80,0x00,0x91,0x00,0x80,0x40,0x47,0x01,0x00,0x02,0xc0,0x00,0x80, +0x80,0x46,0x00,0x80,0x00,0x91,0x00,0x80,0x40,0x47,0x01,0x00,0x04,0xc0,0x00,0x80, +0xc0,0x46,0x00,0x80,0x00,0x91,0x00,0x80,0x40,0x47,0x01,0x00,0x06,0xc0,0x00,0x81, +0x00,0x46,0x00,0x80,0x00,0x91,0x00,0x80,0x40,0x47,0x01,0x00,0x08,0xc0,0x00,0x81, +0x40,0x46,0x00,0x80,0x02,0x84,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x06,0x00,0x0f,0x64,0x65,0x66,0x69,0x6e,0x65,0x5f,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x00,0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42,0x69,0x6e,0x64,0x00, +0x00,0x0a,0x62,0x69,0x6e,0x64,0x5f,0x63,0x6c,0x61,0x73,0x73,0x00,0x00,0x14,0x62, +0x69,0x6e,0x64,0x5f,0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x5f,0x6d,0x65,0x74, +0x68,0x6f,0x64,0x00,0x00,0x12,0x62,0x69,0x6e,0x64,0x5f,0x73,0x74,0x61,0x74,0x69, +0x63,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64,0x00,0x00,0x12,0x62,0x69,0x6e,0x64,0x5f, +0x63,0x75,0x73,0x74,0x6f,0x6d,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64,0x00,0x00,0x00, +0x00,0x52,0x00,0x07,0x00,0x0b,0x00,0x01,0x00,0x00,0x00,0x07,0x0a,0x00,0x00,0x26, +0x03,0x80,0x00,0x11,0x04,0x00,0x01,0x04,0x04,0x80,0xc0,0x01,0x05,0x00,0x01,0x40, +0x03,0x80,0x41,0x21,0x03,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, +0x00,0x06,0x4b,0x65,0x72,0x6e,0x65,0x6c,0x00,0x00,0x04,0x73,0x65,0x6e,0x64,0x00, +0x00,0x0d,0x64,0x65,0x66,0x69,0x6e,0x65,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64,0x00, +0x00,0x00,0x01,0x2e,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0x08, +0x00,0xa6,0x01,0x80,0x40,0x01,0x01,0x80,0x00,0x20,0x01,0x40,0x01,0x19,0x02,0x40, +0x00,0x03,0x00,0x40,0x00,0x97,0x02,0x3f,0xff,0x83,0x01,0x80,0x40,0xac,0x02,0x01, +0x40,0x15,0x01,0x80,0x80,0xa0,0x01,0xc0,0x09,0x19,0x01,0x80,0x00,0x06,0x02,0x00, +0x02,0x11,0x02,0x80,0x00,0x3d,0x03,0x00,0xc0,0x15,0x02,0x81,0x80,0x3e,0x03,0x00, +0x00,0xbd,0x02,0x81,0x80,0x3e,0x03,0x00,0x40,0x01,0x03,0x00,0x00,0x20,0x02,0x81, +0x80,0x3e,0x03,0x00,0x01,0x3d,0x02,0x81,0x80,0x3e,0x03,0x01,0x40,0x15,0x02,0x81, +0x80,0x3e,0x03,0x00,0x01,0xbd,0x02,0x81,0x80,0x3e,0x02,0x01,0x40,0xa0,0x01,0x80, +0xc0,0xa0,0x01,0x80,0x03,0x11,0x02,0x00,0x80,0x15,0x02,0x81,0x00,0x15,0x02,0x01, +0x01,0x37,0x02,0x80,0x40,0x01,0x03,0x00,0x80,0x01,0x03,0x01,0x80,0xb7,0x02,0x80, +0x40,0xac,0x02,0x01,0x40,0x38,0x01,0x81,0xff,0xa0,0x01,0x80,0x00,0x29,0x00,0x00, +0x00,0x04,0x00,0x00,0x01,0x60,0x00,0x00,0x1e,0x27,0x3a,0x20,0x77,0x72,0x6f,0x6e, +0x67,0x20,0x6e,0x75,0x6d,0x62,0x65,0x72,0x20,0x6f,0x66,0x20,0x61,0x72,0x67,0x75, +0x6d,0x65,0x6e,0x74,0x73,0x20,0x28,0x00,0x00,0x05,0x20,0x66,0x6f,0x72,0x20,0x00, +0x00,0x01,0x29,0x00,0x00,0x00,0x08,0x00,0x04,0x73,0x69,0x7a,0x65,0x00,0x00,0x01, +0x2b,0x00,0x00,0x02,0x21,0x3d,0x00,0x00,0x05,0x72,0x61,0x69,0x73,0x65,0x00,0x00, +0x0d,0x41,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x45,0x72,0x72,0x6f,0x72,0x00,0x00, +0x03,0x6e,0x65,0x77,0x00,0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42,0x69,0x6e,0x64, +0x00,0x00,0x0a,0x63,0x61,0x6c,0x6c,0x5f,0x63,0x66,0x75,0x6e,0x63,0x00,0x00,0x00, +0x00,0x4b,0x00,0x07,0x00,0x09,0x00,0x01,0x00,0x00,0x00,0x07,0x0a,0x00,0x00,0x26, +0x03,0x80,0x40,0x01,0x04,0x00,0xc0,0x01,0x03,0x80,0x00,0xa0,0x04,0x00,0x01,0x40, +0x03,0x80,0x40,0x21,0x03,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02, +0x00,0x09,0x63,0x6f,0x6e,0x73,0x74,0x5f,0x67,0x65,0x74,0x00,0x00,0x0a,0x63,0x6c, +0x61,0x73,0x73,0x5f,0x65,0x76,0x61,0x6c,0x00,0x00,0x00,0x00,0x47,0x00,0x01,0x00, +0x04,0x00,0x01,0x00,0x00,0x00,0x05,0x00,0x80,0x00,0x06,0x01,0x00,0x00,0x84,0x01, +0x80,0x01,0x40,0x00,0x80,0x00,0xa1,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x02,0x00,0x0d,0x64,0x65,0x66,0x69,0x6e,0x65,0x5f,0x6d,0x65,0x74,0x68, +0x6f,0x64,0x00,0x00,0x0a,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x69,0x7a,0x65,0x00, +0x00,0x00,0x01,0x2c,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x25,0x00,0x08, +0x00,0xa6,0x01,0x80,0x40,0x01,0x01,0x80,0x00,0x20,0x01,0x40,0x01,0x19,0x02,0x40, +0x00,0x03,0x00,0x40,0x00,0x97,0x02,0x3f,0xff,0x83,0x01,0x80,0x40,0xac,0x02,0x01, +0x40,0x95,0x01,0x80,0x80,0xa0,0x01,0xc0,0x07,0x19,0x01,0x80,0x00,0x06,0x02,0x00, +0x02,0x11,0x02,0x80,0x00,0x3d,0x03,0x00,0x40,0x01,0x03,0x00,0x00,0x20,0x02,0x81, +0x80,0x3e,0x03,0x00,0x00,0xbd,0x02,0x81,0x80,0x3e,0x03,0x01,0x40,0x95,0x02,0x81, +0x80,0x3e,0x03,0x00,0x01,0x3d,0x02,0x81,0x80,0x3e,0x02,0x01,0x40,0xa0,0x01,0x80, +0xc0,0xa0,0x01,0x80,0x03,0x11,0x02,0x00,0x80,0x95,0x02,0x80,0x00,0x06,0x03,0x01, +0x00,0x95,0x02,0x01,0x01,0xb7,0x02,0x80,0x40,0x01,0x03,0x00,0x80,0x01,0x03,0x01, +0x80,0xb7,0x02,0x80,0x40,0xac,0x02,0x01,0x40,0x38,0x01,0x81,0xff,0xa0,0x01,0x80, +0x00,0x29,0x00,0x00,0x00,0x03,0x00,0x00,0x29,0x60,0x69,0x6e,0x69,0x74,0x69,0x61, +0x6c,0x69,0x7a,0x65,0x27,0x3a,0x20,0x77,0x72,0x6f,0x6e,0x67,0x20,0x6e,0x75,0x6d, +0x62,0x65,0x72,0x20,0x6f,0x66,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73, +0x20,0x28,0x00,0x00,0x05,0x20,0x66,0x6f,0x72,0x20,0x00,0x00,0x01,0x29,0x00,0x00, +0x00,0x08,0x00,0x04,0x73,0x69,0x7a,0x65,0x00,0x00,0x01,0x2b,0x00,0x00,0x02,0x21, +0x3d,0x00,0x00,0x05,0x72,0x61,0x69,0x73,0x65,0x00,0x00,0x0d,0x41,0x72,0x67,0x75, +0x6d,0x65,0x6e,0x74,0x45,0x72,0x72,0x6f,0x72,0x00,0x00,0x03,0x6e,0x65,0x77,0x00, +0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42,0x69,0x6e,0x64,0x00,0x00,0x0d,0x63,0x61, +0x6c,0x6c,0x5f,0x63,0x74,0x6f,0x72,0x66,0x75,0x6e,0x63,0x00,0x00,0x00,0x00,0x4b, +0x00,0x08,0x00,0x0a,0x00,0x01,0x00,0x00,0x00,0x07,0x0c,0x00,0x00,0x26,0x04,0x00, +0x40,0x01,0x04,0x80,0xc0,0x01,0x04,0x00,0x00,0xa0,0x04,0x80,0x01,0x40,0x04,0x00, +0x40,0x21,0x04,0x00,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x09, +0x63,0x6f,0x6e,0x73,0x74,0x5f,0x67,0x65,0x74,0x00,0x00,0x0a,0x63,0x6c,0x61,0x73, +0x73,0x5f,0x65,0x76,0x61,0x6c,0x00,0x00,0x00,0x00,0x3a,0x00,0x01,0x00,0x04,0x00, +0x01,0x00,0x00,0x00,0x05,0x00,0x80,0x00,0x06,0x01,0x01,0x00,0x15,0x01,0x80,0x01, +0x40,0x00,0x80,0x00,0xa1,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x00,0x0d,0x64,0x65,0x66,0x69,0x6e,0x65,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64, +0x00,0x00,0x00,0x01,0x34,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x29,0x00, +0x08,0x00,0xa6,0x01,0x80,0x40,0x01,0x01,0x80,0x00,0x20,0x01,0x40,0x01,0x19,0x02, +0x40,0x00,0x03,0x00,0x40,0x00,0x97,0x02,0x3f,0xff,0x83,0x01,0x80,0x40,0xac,0x02, +0x01,0x80,0x95,0x01,0x80,0x80,0xa0,0x01,0xc0,0x09,0x19,0x01,0x80,0x00,0x06,0x02, +0x00,0x02,0x11,0x02,0x80,0x00,0x3d,0x03,0x01,0x00,0x95,0x02,0x81,0x80,0x3e,0x03, +0x00,0x00,0xbd,0x02,0x81,0x80,0x3e,0x03,0x00,0x40,0x01,0x03,0x00,0x00,0x20,0x02, +0x81,0x80,0x3e,0x03,0x00,0x01,0x3d,0x02,0x81,0x80,0x3e,0x03,0x01,0x80,0x95,0x02, +0x81,0x80,0x3e,0x03,0x00,0x01,0xbd,0x02,0x81,0x80,0x3e,0x02,0x01,0x40,0xa0,0x01, +0x80,0xc0,0xa0,0x01,0x80,0x03,0x11,0x02,0x00,0x80,0x95,0x02,0x80,0x00,0x06,0x03, +0x01,0x40,0x95,0x02,0x01,0x01,0xb7,0x02,0x80,0x40,0x01,0x03,0x00,0x80,0x01,0x03, +0x01,0x80,0xb7,0x02,0x80,0x40,0xac,0x02,0x01,0x40,0x38,0x01,0x81,0xff,0xa0,0x01, +0x80,0x00,0x29,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x60,0x00,0x00,0x1e,0x27,0x3a, +0x20,0x77,0x72,0x6f,0x6e,0x67,0x20,0x6e,0x75,0x6d,0x62,0x65,0x72,0x20,0x6f,0x66, +0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x20,0x28,0x00,0x00,0x05,0x20, +0x66,0x6f,0x72,0x20,0x00,0x00,0x01,0x29,0x00,0x00,0x00,0x08,0x00,0x04,0x73,0x69, +0x7a,0x65,0x00,0x00,0x01,0x2b,0x00,0x00,0x02,0x21,0x3d,0x00,0x00,0x05,0x72,0x61, +0x69,0x73,0x65,0x00,0x00,0x0d,0x41,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x45,0x72, +0x72,0x6f,0x72,0x00,0x00,0x03,0x6e,0x65,0x77,0x00,0x00,0x09,0x4d,0x72,0x75,0x62, +0x79,0x42,0x69,0x6e,0x64,0x00,0x00,0x0c,0x63,0x61,0x6c,0x6c,0x5f,0x69,0x6d,0x65, +0x74,0x68,0x6f,0x64,0x00,0x00,0x00,0x00,0x4b,0x00,0x08,0x00,0x0a,0x00,0x01,0x00, +0x00,0x00,0x07,0x0c,0x00,0x00,0x26,0x04,0x00,0x40,0x01,0x04,0x80,0xc0,0x01,0x04, +0x00,0x00,0xa0,0x04,0x80,0x01,0x40,0x04,0x00,0x40,0x21,0x04,0x00,0x00,0x29,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x09,0x63,0x6f,0x6e,0x73,0x74,0x5f,0x67, +0x65,0x74,0x00,0x00,0x0a,0x63,0x6c,0x61,0x73,0x73,0x5f,0x65,0x76,0x61,0x6c,0x00, +0x00,0x00,0x00,0x42,0x00,0x01,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x05,0x00,0x80, +0x00,0x06,0x00,0x80,0x00,0x20,0x01,0x00,0x01,0x40,0x00,0x80,0x40,0x21,0x00,0x80, +0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x05,0x63,0x6c,0x61,0x73, +0x73,0x00,0x00,0x0d,0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x5f,0x65,0x76,0x61, +0x6c,0x00,0x00,0x00,0x00,0x3a,0x00,0x01,0x00,0x04,0x00,0x01,0x00,0x00,0x00,0x05, +0x00,0x80,0x00,0x06,0x01,0x01,0x00,0x95,0x01,0x80,0x01,0x40,0x00,0x80,0x00,0xa1, +0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x0d,0x64,0x65, +0x66,0x69,0x6e,0x65,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64,0x00,0x00,0x00,0x01,0x2e, +0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x28,0x00,0x08,0x00,0xa6,0x01,0x80, +0x40,0x01,0x01,0x80,0x00,0x20,0x01,0x40,0x01,0x19,0x02,0x40,0x00,0x03,0x00,0x40, +0x00,0x97,0x02,0x3f,0xff,0x83,0x01,0x80,0x40,0xac,0x02,0x01,0x81,0x15,0x01,0x80, +0x80,0xa0,0x01,0xc0,0x09,0x19,0x01,0x80,0x00,0x06,0x02,0x00,0x02,0x11,0x02,0x80, +0x00,0x3d,0x03,0x01,0x01,0x15,0x02,0x81,0x80,0x3e,0x03,0x00,0x00,0xbd,0x02,0x81, +0x80,0x3e,0x03,0x00,0x40,0x01,0x03,0x00,0x00,0x20,0x02,0x81,0x80,0x3e,0x03,0x00, +0x01,0x3d,0x02,0x81,0x80,0x3e,0x03,0x01,0x81,0x15,0x02,0x81,0x80,0x3e,0x03,0x00, +0x01,0xbd,0x02,0x81,0x80,0x3e,0x02,0x01,0x40,0xa0,0x01,0x80,0xc0,0xa0,0x01,0x80, +0x03,0x11,0x02,0x00,0x81,0x15,0x02,0x81,0x41,0x15,0x02,0x01,0x01,0x37,0x02,0x80, +0x40,0x01,0x03,0x00,0x80,0x01,0x03,0x01,0x80,0xb7,0x02,0x80,0x40,0xac,0x02,0x01, +0x40,0x38,0x01,0x81,0xff,0xa0,0x01,0x80,0x00,0x29,0x00,0x00,0x00,0x04,0x00,0x00, +0x01,0x60,0x00,0x00,0x1e,0x27,0x3a,0x20,0x77,0x72,0x6f,0x6e,0x67,0x20,0x6e,0x75, +0x6d,0x62,0x65,0x72,0x20,0x6f,0x66,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74, +0x73,0x20,0x28,0x00,0x00,0x05,0x20,0x66,0x6f,0x72,0x20,0x00,0x00,0x01,0x29,0x00, +0x00,0x00,0x08,0x00,0x04,0x73,0x69,0x7a,0x65,0x00,0x00,0x01,0x2b,0x00,0x00,0x02, +0x21,0x3d,0x00,0x00,0x05,0x72,0x61,0x69,0x73,0x65,0x00,0x00,0x0d,0x41,0x72,0x67, +0x75,0x6d,0x65,0x6e,0x74,0x45,0x72,0x72,0x6f,0x72,0x00,0x00,0x03,0x6e,0x65,0x77, +0x00,0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42,0x69,0x6e,0x64,0x00,0x00,0x0a,0x63, +0x61,0x6c,0x6c,0x5f,0x63,0x66,0x75,0x6e,0x63,0x00,0x00,0x00,0x00,0x4b,0x00,0x08, +0x00,0x0a,0x00,0x01,0x00,0x00,0x00,0x07,0x0c,0x00,0x00,0x26,0x04,0x00,0x40,0x01, +0x04,0x80,0xc0,0x01,0x04,0x00,0x00,0xa0,0x04,0x80,0x01,0x40,0x04,0x00,0x40,0x21, +0x04,0x00,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x09,0x63,0x6f, +0x6e,0x73,0x74,0x5f,0x67,0x65,0x74,0x00,0x00,0x0a,0x63,0x6c,0x61,0x73,0x73,0x5f, +0x65,0x76,0x61,0x6c,0x00,0x00,0x00,0x00,0x3a,0x00,0x01,0x00,0x04,0x00,0x01,0x00, +0x00,0x00,0x05,0x00,0x80,0x00,0x06,0x01,0x01,0x00,0x15,0x01,0x80,0x01,0x40,0x00, 0x80,0x00,0xa1,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, 0x0d,0x64,0x65,0x66,0x69,0x6e,0x65,0x5f,0x6d,0x65,0x74,0x68,0x6f,0x64,0x00,0x00, -0x00,0x60,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x0a,0x00,0x08,0x00,0x26,0x01,0x80, -0x00,0x11,0x02,0x00,0x40,0x95,0x02,0x80,0x01,0x0d,0x03,0x01,0x00,0x95,0x02,0x01, -0x01,0xb7,0x02,0x80,0x40,0x01,0x02,0x01,0x40,0x38,0x01,0x80,0x7f,0xa0,0x01,0x80, -0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x09,0x4d,0x72,0x75,0x62, -0x79,0x42,0x69,0x6e,0x64,0x00,0x0c,0x63,0x61,0x6c,0x6c,0x5f,0x63,0x6d,0x65,0x74, -0x68,0x6f,0x64,0x00,0x09,0x40,0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x45,0x4e, -0x44,0x00,0x00,0x00,0x00,0x08, +0x00,0x01,0x3a,0x00,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x2b,0x00,0x08,0x00, +0xa6,0x01,0x80,0x40,0x01,0x01,0x80,0x00,0x20,0x01,0x40,0x01,0x19,0x02,0x40,0x00, +0x03,0x00,0x40,0x00,0x97,0x02,0x3f,0xff,0x83,0x01,0x80,0x40,0xac,0x02,0x01,0x80, +0x95,0x01,0x80,0x80,0xa0,0x01,0xc0,0x09,0x19,0x01,0x80,0x00,0x06,0x02,0x00,0x02, +0x11,0x02,0x80,0x00,0x3d,0x03,0x01,0x00,0x95,0x02,0x81,0x80,0x3e,0x03,0x00,0x00, +0xbd,0x02,0x81,0x80,0x3e,0x03,0x00,0x40,0x01,0x03,0x00,0x00,0x20,0x02,0x81,0x80, +0x3e,0x03,0x00,0x01,0x3d,0x02,0x81,0x80,0x3e,0x03,0x01,0x80,0x95,0x02,0x81,0x80, +0x3e,0x03,0x00,0x01,0xbd,0x02,0x81,0x80,0x3e,0x02,0x01,0x40,0xa0,0x01,0x80,0xc0, +0xa0,0x01,0x80,0x03,0x11,0x02,0x00,0x80,0x95,0x02,0x81,0x40,0x95,0x02,0x01,0x01, +0x37,0x02,0x80,0x00,0x06,0x02,0x81,0x40,0xb7,0x03,0x00,0x40,0x01,0x02,0x80,0x40, +0xac,0x03,0x00,0x80,0x01,0x03,0x01,0x80,0xb7,0x02,0x80,0x40,0xac,0x02,0x01,0x40, +0x38,0x01,0x81,0xff,0xa0,0x01,0x80,0x00,0x29,0x00,0x00,0x00,0x04,0x00,0x00,0x01, +0x60,0x00,0x00,0x1e,0x27,0x3a,0x20,0x77,0x72,0x6f,0x6e,0x67,0x20,0x6e,0x75,0x6d, +0x62,0x65,0x72,0x20,0x6f,0x66,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73, +0x20,0x28,0x00,0x00,0x05,0x20,0x66,0x6f,0x72,0x20,0x00,0x00,0x01,0x29,0x00,0x00, +0x00,0x08,0x00,0x04,0x73,0x69,0x7a,0x65,0x00,0x00,0x01,0x2b,0x00,0x00,0x02,0x21, +0x3d,0x00,0x00,0x05,0x72,0x61,0x69,0x73,0x65,0x00,0x00,0x0d,0x41,0x72,0x67,0x75, +0x6d,0x65,0x6e,0x74,0x45,0x72,0x72,0x6f,0x72,0x00,0x00,0x03,0x6e,0x65,0x77,0x00, +0x00,0x09,0x4d,0x72,0x75,0x62,0x79,0x42,0x69,0x6e,0x64,0x00,0x00,0x0a,0x63,0x61, +0x6c,0x6c,0x5f,0x63,0x66,0x75,0x6e,0x63,0x00,0x45,0x4e,0x44,0x00,0x00,0x00,0x00, +0x08, }; diff --git a/mrubybind.h b/mrubybind.h index 8c5310f..8abbed3 100644 --- a/mrubybind.h +++ b/mrubybind.h @@ -1,47 +1,5284 @@ +// Do not modify this file directly, this is generated +/** + * mrubybind - Binding library for mruby/C++ + * + * Usage: + * 1. Prepare a function which you want to call from mruby: + * > int square(int x) { return x * x; } + * + * 2. Create MrubyBind instance: + * > MrubyBind b(mirb) + * + * 3. Bind a function: + * > b.bind("square", square); + * + * 4. You can call it from mruby: + * > puts square(1111) #=> 1234321 + * + * There are other methods to bind constant/class/instance method in + * MrubyBind. Please see the definition of MrubyBind + * (the bottom of this file), or README. + */ #ifndef __MRUBYBIND_H__ #define __MRUBYBIND_H__ -#include "mrubybind_types.h" - -namespace mrubybind { - -class MrubyBind { - public: - MrubyBind(mrb_state* mrb); - - // Bind function. - template - void bind(const char* name, Func f) { - mrb_value binder = mrb_voidp_value((void*)Binder::call); - mrb_value fn = mrb_str_new_cstr(mrb, name); - mrb_value fp = mrb_voidp_value((void*)f); - mrb_funcall(mrb, mod_mrubybind, "define_function", 3, binder, fn, fp); - } - - // Bind class. - template - void define_class(const char* class_name, Func f) { - mrb_value binder = mrb_voidp_value((void*)Binder::call); - mrb_value cn = mrb_str_new_cstr(mrb, class_name); - mrb_value fp = mrb_voidp_value((void*)f); - mrb_funcall(mrb, mod_mrubybind, "create_class", 3, binder, cn, fp); - } +#ifndef __cplusplus +#error mrubybind can be used from C++ only. +#endif - // Bind class method. - template - void define_class_method(const char* class_name, const char* method_name, Method m) { - mrb_value binder = mrb_voidp_value((void*)Binder::call); - mrb_value cn = mrb_str_new_cstr(mrb, class_name); - mrb_value mn = mrb_str_new_cstr(mrb, method_name); - mrb_value mp = mrb_str_new(mrb, (char*)&m, sizeof(m)); - mrb_funcall(mrb, mod_mrubybind, "define_class_method", 4, binder, cn, mn, mp); - } +#include "mruby.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/proc.h" +#include "mruby/variable.h" +//#include "mrubybind_types.h" - private: - mrb_state* mrb; - mrb_value mod_mrubybind; -}; +#include +#include +// Describe type conversion between C type value and mruby value. + +#include "mruby/string.h" +#include "mruby/proc.h" +#include "mruby/array.h" +#include "mruby/hash.h" +#include "mruby/variable.h" +#include +#include +#include +#include +#include + +namespace mrubybind { + +extern const char* untouchable_table; +extern const char* untouchable_object; + +class MrubyArenaStore{ + mrb_state* mrb; + int ai; +public: + MrubyArenaStore(mrb_state* mrb) + { + this->mrb = mrb; + this->ai = mrb_gc_arena_save(mrb); + } + + ~MrubyArenaStore() + { + mrb_gc_arena_restore(mrb, ai); + } + +}; + +class MrubyBindStatus{ + +public: + + struct Data; + typedef std::shared_ptr Data_ptr; + typedef std::map Table; + + struct ObjectInfo + { + size_t ref_count; + size_t id; + + ObjectInfo() + { + this->ref_count = 0; + this->id = 0; + } + + ObjectInfo(size_t id) + { + this->ref_count = 1; + this->id = id; + } + }; + typedef std::map ObjectIdTable; + typedef std::vector FreeIdArray; + + static Table& get_living_table(){ + static Table table; + return table; + } + + struct Data{ + typedef std::map > ClassConvertableTable; + + + mrb_state* mrb; + mrb_value avoid_gc_table; + ClassConvertableTable class_convertable_table; + ObjectIdTable object_id_table; + FreeIdArray free_id_array; + + Data(){ + + } + ~Data(){ + + } + + mrb_state* get_mrb(){ + return mrb; + } + + mrb_value get_avoid_gc_table(){ + return avoid_gc_table; + } + + size_t new_id() + { + return mrb_ary_len(mrb, avoid_gc_table); + } + + ObjectIdTable& get_object_id_table() + { + return object_id_table; + } + + FreeIdArray& get_free_id_array() + { + return free_id_array; + } + + void set_class_conversion(const std::string& s, const std::string& d, bool c){ + class_convertable_table[s][d] = c; + } + + bool is_convertable(const std::string& s, const std::string& d) + { + auto fs = class_convertable_table.find(s); + if(fs != class_convertable_table.end()){ + auto fd = fs->second.find(d); + if(fd != fs->second.end()){ + return fd->second; + } + } + return false; + } + + }; + + MrubyBindStatus(){ + + } + + MrubyBindStatus(mrb_state* mrb, mrb_value avoid_gc_table){ + + Table& living_table = get_living_table(); + data = std::make_shared(); + data->mrb = mrb; + data->avoid_gc_table = avoid_gc_table; + living_table[mrb] = data; + } + + ~MrubyBindStatus(){ + + Table& living_table = MrubyBindStatus::get_living_table(); + living_table.erase(data->mrb); + data->mrb = NULL; + + } + + static bool is_living(mrb_state* mrb){ + Table& living_table = get_living_table(); + if(living_table.find(mrb) != living_table.end()){ + return living_table[mrb].get(); + } + return false; + } + + static Data_ptr search(mrb_state* mrb){ + Table& living_table = get_living_table(); + if(living_table.find(mrb) != living_table.end()){ + return living_table[mrb]; + } + return Data_ptr(NULL); + } + + + +private: + std::shared_ptr data; +}; + +template class Deleter{ + MrubyBindStatus::Data_ptr mrbsp; + mrb_value v_; +public: + Deleter() + { + + } + + Deleter(mrb_state* mrb, mrb_value v){ + if(!mrb_immediate_p(v)) + { + mrbsp = MrubyBindStatus::search(mrb); + mrb_value avoid_gc_table = mrbsp->get_avoid_gc_table(); + auto& object_id_table = mrbsp->get_object_id_table(); + auto& free_id_array = mrbsp->get_free_id_array(); + if(object_id_table.find(mrb_basic_ptr(v)) == object_id_table.end()) + { + size_t new_id; + if(!free_id_array.empty()) + { + new_id = free_id_array.back(); + free_id_array.pop_back(); + mrb_ary_set(mrb, avoid_gc_table, (mrb_int)new_id, v); + } + else + { + new_id = mrbsp->new_id(); + mrb_ary_push(mrb, avoid_gc_table, v); + } + object_id_table[mrb_basic_ptr(v)] = MrubyBindStatus::ObjectInfo(new_id); + } + else + { + object_id_table[mrb_basic_ptr(v)].ref_count++; + } + } + v_ = v; + + } + ~Deleter(){ + + } + mrb_state* get_mrb(){ + return mrbsp->mrb; + } + void operator()(T* p) const { + if(mrbsp.get()){ + mrb_state* mrb = mrbsp->get_mrb(); + if(mrb){ + mrb_value v = v_; + if(!mrb_immediate_p(v)) + { + mrb_value avoid_gc_table = mrbsp->get_avoid_gc_table(); + auto& object_id_table = mrbsp->get_object_id_table(); + auto& free_id_array = mrbsp->get_free_id_array(); + auto& oi = object_id_table[mrb_basic_ptr(v)]; + oi.ref_count--; + if(oi.ref_count <= 0) + { + mrb_ary_set(mrb, avoid_gc_table, (mrb_int)oi.id, mrb_nil_value()); + free_id_array.push_back(oi.id); + object_id_table.erase(mrb_basic_ptr(v)); + } + } + + + } + } + if(p){ + delete p; + } + } + +}; + +template using obj_ptr = std::shared_ptr; +//template using FuncPtr = std::shared_ptr >; + +template class FuncPtr{ + mrb_state* mrb; + std::shared_ptr > p; +public: + FuncPtr(){ + + } + templateFuncPtr(std::function* pt, D d) : p(pt, d){ + mrb = d.get_mrb(); + } + ~FuncPtr(){ + + } + const std::shared_ptr >& ref() const{ + return p; + } + bool is_living() const{ + return MrubyBindStatus::is_living(mrb); + } + std::function& func() const{ + if(!p.get()){ + throw std::runtime_error("empty function."); + } + return *p.get(); + } + operator bool() const { + if(!p.get()){ + return false; + } + return (bool)*p.get(); + } + void reset(){ + p.reset(); + } + template void reset(Y* y){ + p.reset(y); + } + template void reset(Y* y, D d){ + p.reset(y, d); + } + template void reset(Y* y, D d, A a){ + p.reset(y, d, a); + } +}; + +template Deleter set_avoid_gc(mrb_state* mrb, mrb_value v){ + return Deleter(mrb, v); +} + +template obj_ptr make_obj_ptr(Deleter d, T t){ + T* pt = new T(); + *pt = t; + return obj_ptr(pt, d); +} + +template FuncPtr make_FuncPtr(Deleter > d, std::function t){ + std::function* pt = new std::function(); + *pt = t; + return FuncPtr(pt, d); +} + +template +struct Type; + +class MrubyRef{ + mrb_state* mrb; + std::shared_ptr v; +public: + + MrubyRef(); + MrubyRef(mrb_state* mrb, const mrb_value& v); + ~MrubyRef(); + + bool is_living() const; + mrb_state* get_mrb() const; + mrb_value get_v()const; + bool empty() const; + bool test() const; + bool obj_equal(const MrubyRef& r) const; + std::string to_s() const; + int to_i() const; + float to_float() const; + double to_double() const; + + MrubyRef call(std::string name); + +#include "mrubybind_call_generated.h" + +}; + +//=========================================================================== +// C <-> mruby type converter. + +//template +//struct Type { + // Type name used for error message. + // static const char TYPE_NAME[]; + + // Returns whether the given mrb_value can be converted into type T. + //static int check(mrb_value v) = 0; + + // Converts mrb_value to type T value. + //static T get(mrb_value v) = 0; + + // Converts type T value to mrb_value. + //static mrb_value ret(mrb_state*, T i) = 0; +//}; + +// Fixnum +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_fixnum_p(v) || mrb_float_p(v); } + static int get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_fixnum_p(v) ? mrb_fixnum(v) : mrb_float(v); } + static mrb_value ret(mrb_state*, int i) { return mrb_fixnum_value(i); } +}; + +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_fixnum_p(v) || mrb_float_p(v); } + static unsigned int get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_fixnum_p(v) ? mrb_fixnum(v) : mrb_float(v); } + static mrb_value ret(mrb_state*, unsigned int i) { return mrb_fixnum_value(i); } +}; + +// float +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_float_p(v) || mrb_fixnum_p(v); } + static float get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_float_p(v) ? mrb_float(v) : mrb_fixnum(v); } + static mrb_value ret(mrb_state* mrb, float f) { return mrb_float_value(mrb, f); } +}; + +// double +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_float_p(v) || mrb_fixnum_p(v); } + static double get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_float_p(v) ? mrb_float(v) : mrb_fixnum(v); } + static mrb_value ret(mrb_state* mrb, double f) { return mrb_float_value(mrb, f); } +}; + +// String +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_string_p(v); } + static const char* get(mrb_state* mrb, mrb_value v) { (void)mrb; return RSTRING_PTR(v); } + static mrb_value ret(mrb_state* mrb, const char* s) { return mrb_str_new_cstr(mrb, s); } +}; + +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_string_p(v); } + static const std::string get(mrb_state* mrb, mrb_value v) { (void)mrb; return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } + static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } +}; + +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_string_p(v); } + static const std::string get(mrb_state* mrb, mrb_value v) { (void)mrb; return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } + static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } +}; + +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_string_p(v); } + static const std::string get(mrb_state* mrb, mrb_value v) { (void)mrb; return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } + static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } +}; + +// Boolean +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value /*v*/) { return 1; } + static bool get(mrb_state* mrb, mrb_value v) { (void)mrb; return mrb_test(v); } + static mrb_value ret(mrb_state* /*mrb*/, bool b) { return b ? mrb_true_value() : mrb_false_value(); } +}; + +// Raw pointer +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value v) { return mrb_cptr_p(v); } + static void* get(mrb_state*, mrb_value v) { return mrb_cptr(v); } + static mrb_value ret(mrb_state* mrb, void* p) { return mrb_cptr_value(mrb, p); } +}; + +// Function +struct TypeFuncBase{ + static const char TYPE_NAME[]; +}; + +template +struct Type > :public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](){ + MrubyArenaStore mas(mrb); + return Type::get(mrb, mrb_yield(mrb, v, mrb_nil_value())); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +template<> +struct Type > :public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](){ + MrubyArenaStore mas(mrb); + mrb_yield(mrb, v, mrb_nil_value()); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// mruby value +template<> +struct Type { + static const char TYPE_NAME[]; + static int check(mrb_state*, mrb_value) { return 1; } + static MrubyRef get(mrb_state* mrb, mrb_value v) { (void)mrb; return MrubyRef(mrb, v); } + static mrb_value ret(mrb_state*, MrubyRef r) { return r.get_v(); } +}; + + +#include "mrubybind_types_generated.h" + +//=========================================================================== +// Binder + +// Template class for Binder. +// Binder template class is specialized with type. +template +struct Binder { + // Template specialization. + //static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) = 0; +}; + +// Template class for Binder. +// Binder template class is specialized with type. +template +struct ClassBinder { + static struct mrb_data_type type_info; + static void dtor(mrb_state*, void* p) { + C* instance = static_cast(p); + delete instance; + } + + // Template specialization. + //static void ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { +}; +template +mrb_data_type ClassBinder::type_info = { "???", dtor }; + +template +struct CustomClassBinder { + // Template specialization. + //static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) = 0; +}; + +// Other Class +struct TypeClassBase{ + static const char TYPE_NAME[]; +}; + +template struct Type :public TypeClassBase { + static std::string class_name; + static int check(mrb_state* mrb, mrb_value v) { + return mrb_type(v) == MRB_TT_DATA && + MrubyBindStatus::search(mrb)->is_convertable(mrb_obj_classname(mrb, v), class_name); + } + static T& get(mrb_state* mrb, mrb_value v) { + (void)mrb; return *(T*)DATA_PTR(v); + } + static mrb_value ret(mrb_state* mrb, T t) { + RClass* cls; + mrb_value v; + cls = mrb_class_get(mrb, class_name.c_str()); + v = mrb_class_new_instance(mrb, 0, NULL, cls); + DATA_TYPE(v) = &ClassBinder::type_info; + T* nt = new T(); + *nt = t; + DATA_PTR(v) = nt; + return v; + } +}; + +template std::string Type::class_name = ""; + +template struct Type :public TypeClassBase { + static std::string class_name; + static int check(mrb_state* mrb, mrb_value v) { + return mrb_type(v) == MRB_TT_DATA && + MrubyBindStatus::search(mrb)->is_convertable(mrb_obj_classname(mrb, v), class_name); + } + static T get(mrb_state* mrb, mrb_value v) { + (void)mrb; return *(T*)DATA_PTR(v); + } + static mrb_value ret(mrb_state* mrb, T t) { + RClass* cls; + mrb_value v; + cls = mrb_class_get(mrb, class_name.c_str()); + v = mrb_class_new_instance(mrb, 0, NULL, cls); + DATA_TYPE(v) = &ClassBinder::type_info; + T* nt = new T(); + *nt = t; + DATA_PTR(v) = nt; + return v; + } +}; + +template std::string Type::class_name = ""; + +// +mrb_value raise(mrb_state *mrb, int parameter_index, + const char* required_type_name, mrb_value value); +mrb_value raisenarg(mrb_state *mrb, mrb_value func_name, int narg, int nparam); + +// Includes generated template specialization. +//#include "mrubybind.inc" +// This file is generated from gen_template.rb +#define ARG(mrb, i) Type::get(mrb, args[i]) +#define ARGSHIFT(mrb, i, j) Type::get(mrb, args[j]) +#define CHECK(i) {if(!Type::check(mrb, args[i])) return RAISE(i);} +#define CHECKSHIFT(i, j) {if(!Type::check(mrb, args[j])) return RAISE(j);} +#define RAISE(i) raise(mrb, i, Type::TYPE_NAME, args[i]) +#define CHECKNARG(narg) {if(narg != NPARAM) RAISENARG(narg);} +#define RAISENARG(narg) raisenarg(mrb, mrb_cfunc_env_get(mrb, 1), narg, NPARAM) + +// void f(void); +template<> +struct Binder { + static const int NPARAM = 0; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(void) = (void (*)(void))mrb_cptr(cfunc); + fp(); + return mrb_nil_value(); + } +}; + +// R f(void); +template +struct Binder { + static const int NPARAM = 0; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(void) = (R (*)(void))mrb_cptr(cfunc); + R result = fp(); + return Type::ret(mrb, result); + } +}; + +// C* ctor(void); +template +struct ClassBinder { + static const int NPARAM = 0; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(void) = (C* (*)(void))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(void) }; +template +struct ClassBinder { + static const int NPARAM = 0; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(void); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(); + return mrb_nil_value(); + } +}; + +// class C { R f(void) }; +template +struct ClassBinder { + static const int NPARAM = 0; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(void); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(); + return Type::ret(mrb, result); + } +}; + +// void f(P0); +template +struct Binder { + static const int NPARAM = 1; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0) = (void (*)(P0))mrb_cptr(cfunc); + fp(ARG(mrb, 0)); + return mrb_nil_value(); + } +}; + +// R f(P0); +template +struct Binder { + static const int NPARAM = 1; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0) = (R (*)(P0))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0); +template +struct ClassBinder { + static const int NPARAM = 1; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0) = (C* (*)(P0))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0) }; +template +struct ClassBinder { + static const int NPARAM = 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0) }; +template +struct ClassBinder { + static const int NPARAM = 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 1 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 1 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 1 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 1 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1); +template +struct Binder { + static const int NPARAM = 2; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1) = (void (*)(P0, P1))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1); +template +struct Binder { + static const int NPARAM = 2; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1) = (R (*)(P0, P1))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1); +template +struct ClassBinder { + static const int NPARAM = 2; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1) = (C* (*)(P0, P1))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1) }; +template +struct ClassBinder { + static const int NPARAM = 2; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1) }; +template +struct ClassBinder { + static const int NPARAM = 2; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 2 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 2 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 2 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 2 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2); +template +struct Binder { + static const int NPARAM = 3; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2) = (void (*)(P0, P1, P2))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2); +template +struct Binder { + static const int NPARAM = 3; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2) = (R (*)(P0, P1, P2))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2); +template +struct ClassBinder { + static const int NPARAM = 3; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2) = (C* (*)(P0, P1, P2))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2) }; +template +struct ClassBinder { + static const int NPARAM = 3; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2) }; +template +struct ClassBinder { + static const int NPARAM = 3; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 3 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 3 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 3 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 3 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3); +template +struct Binder { + static const int NPARAM = 4; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3) = (void (*)(P0, P1, P2, P3))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3); +template +struct Binder { + static const int NPARAM = 4; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3) = (R (*)(P0, P1, P2, P3))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3); +template +struct ClassBinder { + static const int NPARAM = 4; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3) = (C* (*)(P0, P1, P2, P3))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3) }; +template +struct ClassBinder { + static const int NPARAM = 4; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3) }; +template +struct ClassBinder { + static const int NPARAM = 4; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 4 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 4 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 4 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 4 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4); +template +struct Binder { + static const int NPARAM = 5; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4) = (void (*)(P0, P1, P2, P3, P4))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4); +template +struct Binder { + static const int NPARAM = 5; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4) = (R (*)(P0, P1, P2, P3, P4))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4); +template +struct ClassBinder { + static const int NPARAM = 5; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4) = (C* (*)(P0, P1, P2, P3, P4))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4) }; +template +struct ClassBinder { + static const int NPARAM = 5; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4) }; +template +struct ClassBinder { + static const int NPARAM = 5; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 5 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 5 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 5 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 5 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5); +template +struct Binder { + static const int NPARAM = 6; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5) = (void (*)(P0, P1, P2, P3, P4, P5))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5); +template +struct Binder { + static const int NPARAM = 6; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5) = (R (*)(P0, P1, P2, P3, P4, P5))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5); +template +struct ClassBinder { + static const int NPARAM = 6; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5) = (C* (*)(P0, P1, P2, P3, P4, P5))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5) }; +template +struct ClassBinder { + static const int NPARAM = 6; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5) }; +template +struct ClassBinder { + static const int NPARAM = 6; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 6 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 6 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 6 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 6 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6); +template +struct Binder { + static const int NPARAM = 7; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6) = (void (*)(P0, P1, P2, P3, P4, P5, P6))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6); +template +struct Binder { + static const int NPARAM = 7; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6) = (R (*)(P0, P1, P2, P3, P4, P5, P6))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6); +template +struct ClassBinder { + static const int NPARAM = 7; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6) = (C* (*)(P0, P1, P2, P3, P4, P5, P6))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6) }; +template +struct ClassBinder { + static const int NPARAM = 7; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6) }; +template +struct ClassBinder { + static const int NPARAM = 7; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 7 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 7 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 7 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 7 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7); +template +struct Binder { + static const int NPARAM = 8; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7); +template +struct Binder { + static const int NPARAM = 8; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7); +template +struct ClassBinder { + static const int NPARAM = 8; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7) }; +template +struct ClassBinder { + static const int NPARAM = 8; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7) }; +template +struct ClassBinder { + static const int NPARAM = 8; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 8 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 8 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 8 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 8 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8); +template +struct Binder { + static const int NPARAM = 9; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8); +template +struct Binder { + static const int NPARAM = 9; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8); +template +struct ClassBinder { + static const int NPARAM = 9; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8) }; +template +struct ClassBinder { + static const int NPARAM = 9; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8) }; +template +struct ClassBinder { + static const int NPARAM = 9; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 9 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 9 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 9 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 9 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); +template +struct Binder { + static const int NPARAM = 10; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); +template +struct Binder { + static const int NPARAM = 10; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); +template +struct ClassBinder { + static const int NPARAM = 10; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) }; +template +struct ClassBinder { + static const int NPARAM = 10; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) }; +template +struct ClassBinder { + static const int NPARAM = 10; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 10 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 10 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 10 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 10 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); +template +struct Binder { + static const int NPARAM = 11; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); +template +struct Binder { + static const int NPARAM = 11; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); +template +struct ClassBinder { + static const int NPARAM = 11; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) }; +template +struct ClassBinder { + static const int NPARAM = 11; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) }; +template +struct ClassBinder { + static const int NPARAM = 11; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 11 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 11 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 11 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 11 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); +template +struct Binder { + static const int NPARAM = 12; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); +template +struct Binder { + static const int NPARAM = 12; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); +template +struct ClassBinder { + static const int NPARAM = 12; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) }; +template +struct ClassBinder { + static const int NPARAM = 12; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) }; +template +struct ClassBinder { + static const int NPARAM = 12; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 12 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 12 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 12 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 12 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); +template +struct Binder { + static const int NPARAM = 13; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); +template +struct Binder { + static const int NPARAM = 13; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); +template +struct ClassBinder { + static const int NPARAM = 13; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) }; +template +struct ClassBinder { + static const int NPARAM = 13; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) }; +template +struct ClassBinder { + static const int NPARAM = 13; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 13 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 13 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 13 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 13 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); +template +struct Binder { + static const int NPARAM = 14; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); +template +struct Binder { + static const int NPARAM = 14; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); +template +struct ClassBinder { + static const int NPARAM = 14; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) }; +template +struct ClassBinder { + static const int NPARAM = 14; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) }; +template +struct ClassBinder { + static const int NPARAM = 14; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 14 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 14 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 14 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 14 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); +template +struct Binder { + static const int NPARAM = 15; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); +template +struct Binder { + static const int NPARAM = 15; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); +template +struct ClassBinder { + static const int NPARAM = 15; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) }; +template +struct ClassBinder { + static const int NPARAM = 15; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) }; +template +struct ClassBinder { + static const int NPARAM = 15; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 15 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 15 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 15 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 15 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); +template +struct Binder { + static const int NPARAM = 16; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); +template +struct Binder { + static const int NPARAM = 16; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); +template +struct ClassBinder { + static const int NPARAM = 16; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) }; +template +struct ClassBinder { + static const int NPARAM = 16; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) }; +template +struct ClassBinder { + static const int NPARAM = 16; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 16 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); CHECKSHIFT(15, 14); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13), ARGSHIFT(mrb, 15, 14)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 16 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); CHECKSHIFT(15, 14); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13), ARGSHIFT(mrb, 15, 14)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 16 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); CHECKSHIFT(15, 14); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13), ARGSHIFT(mrb, 15, 14)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 16 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); CHECKSHIFT(15, 14); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13), ARGSHIFT(mrb, 15, 14)); + return Type::ret(mrb, result); + } +}; + + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); +template +struct Binder { + static const int NPARAM = 17; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); CHECK(16); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))mrb_cptr(cfunc); + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15), ARG(mrb, 16)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); +template +struct Binder { + static const int NPARAM = 17; + static mrb_value call(mrb_state* mrb, mrb_value /*self*/) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); CHECK(16); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))mrb_cptr(cfunc); + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15), ARG(mrb, 16)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); +template +struct ClassBinder { + static const int NPARAM = 17; + static mrb_value ctor(mrb_state* mrb, mrb_value self) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); CHECK(16); + mrb_value cfunc = mrb_cfunc_env_get(mrb, 0); + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))mrb_cptr(cfunc); + if(ctor) + { + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15), ARG(mrb, 16)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) }; +template +struct ClassBinder { + static const int NPARAM = 17; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); CHECK(16); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); + M mp = *(M*)RSTRING_PTR(cmethod); + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15), ARG(mrb, 16)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) }; +template +struct ClassBinder { + static const int NPARAM = 17; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECK(0); CHECK(1); CHECK(2); CHECK(3); CHECK(4); CHECK(5); CHECK(6); CHECK(7); CHECK(8); CHECK(9); CHECK(10); CHECK(11); CHECK(12); CHECK(13); CHECK(14); CHECK(15); CHECK(16); + C* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9), ARG(mrb, 10), ARG(mrb, 11), ARG(mrb, 12), ARG(mrb, 13), ARG(mrb, 14), ARG(mrb, 15), ARG(mrb, 16)); + return Type::ret(mrb, result); + } +}; + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 17 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); CHECKSHIFT(15, 14); CHECKSHIFT(16, 15); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13), ARGSHIFT(mrb, 15, 14), ARGSHIFT(mrb, 16, 15)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 17 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); CHECKSHIFT(15, 14); CHECKSHIFT(16, 15); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13), ARGSHIFT(mrb, 15, 14), ARGSHIFT(mrb, 16, 15)); + return Type::ret(mrb, result); + } +}; + + + +// custom method +template +struct CustomClassBinder { + static const int NPARAM = 17 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); CHECKSHIFT(15, 14); CHECKSHIFT(16, 15); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef void (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); + M mp = *(M*)RSTRING_PTR(cmethod); + mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13), ARGSHIFT(mrb, 15, 14), ARGSHIFT(mrb, 16, 15)); + return mrb_nil_value(); + } +}; + +template +struct CustomClassBinder { + static const int NPARAM = 17 - 1; + static mrb_value call(mrb_state* mrb, mrb_value self) { + mrb_value* targs; + int narg; + mrb_value block = mrb_nil_value(); + std::vector args; + mrb_get_args(mrb, "*|&", &targs, &narg, &block); + args.resize(narg); + if(narg > 0){ + ::memmove(&args[0], &targs[0], narg * sizeof(mrb_value)); + } + if(mrb_test(block)){ + args.push_back(block); + narg++; + } + CHECKNARG(narg); CHECKSHIFT(1, 0); CHECKSHIFT(2, 1); CHECKSHIFT(3, 2); CHECKSHIFT(4, 3); CHECKSHIFT(5, 4); CHECKSHIFT(6, 5); CHECKSHIFT(7, 6); CHECKSHIFT(8, 7); CHECKSHIFT(9, 8); CHECKSHIFT(10, 9); CHECKSHIFT(11, 10); CHECKSHIFT(12, 11); CHECKSHIFT(13, 12); CHECKSHIFT(14, 13); CHECKSHIFT(15, 14); CHECKSHIFT(16, 15); + P0* instance = static_cast(DATA_PTR(self)); + mrb_value cmethod = mrb_cfunc_env_get(mrb, 0); + typedef R (*M)(P0&, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16); + M mp = *(M*)RSTRING_PTR(cmethod); + R result = mp(*instance, ARGSHIFT(mrb, 1, 0), ARGSHIFT(mrb, 2, 1), ARGSHIFT(mrb, 3, 2), ARGSHIFT(mrb, 4, 3), ARGSHIFT(mrb, 5, 4), ARGSHIFT(mrb, 6, 5), ARGSHIFT(mrb, 7, 6), ARGSHIFT(mrb, 8, 7), ARGSHIFT(mrb, 9, 8), ARGSHIFT(mrb, 10, 9), ARGSHIFT(mrb, 11, 10), ARGSHIFT(mrb, 12, 11), ARGSHIFT(mrb, 13, 12), ARGSHIFT(mrb, 14, 13), ARGSHIFT(mrb, 15, 14), ARGSHIFT(mrb, 16, 15)); + return Type::ret(mrb, result); + } +}; + + +#undef ARG +#undef CHECK } // namespace mrubybind - -#endif + +namespace mrubybind { + +//=========================================================================== +// MrubyBind - utility class for binding C functions/classes to mruby. +class MrubyBind { +public: + MrubyBind(mrb_state* mrb); + MrubyBind(mrb_state* mrb, RClass* mod); + ~MrubyBind(); + + // Bind constant value. + template + void bind_const(const char* name, T v) { + MrubyArenaStore store(mrb_); + mrb_define_const(mrb_, mod_, name, Type::ret(mrb_, v)); + } + + template + void bind_const(const char* module_name, const char* class_name, const char* name, T v) { + MrubyArenaStore store(mrb_); + + struct RClass * tc = DefineClass(module_name, class_name); + + mrb_define_const(mrb_, tc, name, Type::ret(mrb_, v)); + } + + // Bind function. + template + void bind(const char* func_name, Func func_ptr) { + MrubyArenaStore store(mrb_); + mrb_sym func_name_s = mrb_intern_cstr(mrb_, func_name); + mrb_value env[] = { + mrb_cptr_value(mrb_, (void*)func_ptr), // 0: c function pointer + mrb_symbol_value(func_name_s), // 1: function name + }; + struct RProc* proc = mrb_proc_new_cfunc_with_env(mrb_, Binder::call, 2, env); + mrb_field_write_barrier(mrb_, (RBasic *)proc, (RBasic *)proc->env); + if (mod_ == mrb_->kernel_module) + mrb_define_method_raw(mrb_, mod_, func_name_s, proc); + else + mrb_define_class_method_raw(mrb_, mod_, func_name_s, proc); + } + + // Bind class. + template + void bind_class(const char* class_name, Func new_func_ptr) { + MrubyArenaStore store(mrb_); + struct RClass *tc = mrb_define_class(mrb_, class_name, mrb_->object_class); + MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA); + BindInstanceMethod(class_name, "initialize", + mrb_cptr_value(mrb_, (void*)new_func_ptr), + ClassBinder::ctor); + } + + // Bind class.(no new func) + template + void bind_class(const char* module_name, const char* class_name) { + MrubyArenaStore store(mrb_); + + struct RClass * tc = DefineClass(module_name, class_name); + std::string name; + if(module_name){ + name += module_name; + name += "::"; + } + name += class_name; + + Type::class_name = name; + Type::class_name = name; + MrubyBindStatus::search(mrb_)->set_class_conversion(name, name, true); + MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA); + BindInstanceMethod(module_name, class_name, "initialize", + mrb_cptr_value(mrb_, NULL), + ClassBinder::ctor); + } + + template + void bind_class(const char* class_name) { + bind_class(NULL, class_name); + } + + // Bind instance method. + template + void bind_instance_method(const char* class_name, const char* method_name, + Method method_ptr) { + MrubyArenaStore store(mrb_); + mrb_value method_pptr_v = mrb_str_new(mrb_, + reinterpret_cast(&method_ptr), + sizeof(method_ptr)); + BindInstanceMethod(class_name, method_name, + method_pptr_v, ClassBinder::call); + } + + // Bind static method. + template + void bind_static_method(const char* module_name, const char* class_name, const char* method_name, + Method method_ptr) { + MrubyArenaStore store(mrb_); + mrb_sym method_name_s = mrb_intern_cstr(mrb_, method_name); + mrb_value env[] = { + mrb_cptr_value(mrb_, (void*)method_ptr), // 0: method pointer + mrb_symbol_value(method_name_s), // 1: method name + }; + struct RProc* proc = mrb_proc_new_cfunc_with_env(mrb_, Binder::call, 2, env); + mrb_field_write_barrier(mrb_, (RBasic *)proc, (RBasic *)proc->env); + struct RClass* klass = GetClass(module_name, class_name); + mrb_define_class_method_raw(mrb_, klass, method_name_s, proc); + } + + template + void bind_static_method(const char* class_name, const char* method_name, + Method method_ptr) { + bind_static_method(NULL, class_name, method_name, + method_ptr); + } + + // Bind custom method. + template + void bind_custom_method(const char* module_name, const char* class_name, const char* method_name, Func func_ptr) { + MrubyArenaStore store(mrb_); + mrb_value (*binder_func)(mrb_state*, mrb_value) = CustomClassBinder::call; + mrb_value original_func_v = mrb_str_new(mrb_, + reinterpret_cast(&func_ptr), + sizeof(func_ptr)); + mrb_sym method_name_s = mrb_intern_cstr(mrb_, method_name); + mrb_value env[] = { + original_func_v, // 0: c function pointer + mrb_symbol_value(method_name_s), // 1: method name + }; + struct RProc* proc = mrb_proc_new_cfunc_with_env(mrb_, binder_func, 2, env); + mrb_field_write_barrier(mrb_, (RBasic *)proc, (RBasic *)proc->env); + struct RClass* klass = GetClass(module_name, class_name); + mrb_define_method_raw(mrb_, klass, method_name_s, proc); + } + + template + void bind_custom_method(const char* class_name, const char* method_name, Func func_ptr) { + bind_custom_method(NULL, class_name, method_name, func_ptr); + } + + //add convertable class pair + void add_convertable(const char* class_name_first, const char* class_name_second) + { + MrubyBindStatus::search(mrb_)->set_class_conversion(class_name_first, class_name_second, true); + MrubyBindStatus::search(mrb_)->set_class_conversion(class_name_second, class_name_first, true); + } + + mrb_state* get_mrb(){ + return mrb_; + } + mrb_value get_avoid_gc_table(){ + return avoid_gc_table_; + } + +private: + void Initialize(); + + // Returns mruby class under a module. + std::vector SplitModule(const char* module_name); + struct RClass* DefineModule(const char* module_name); + struct RClass* DefineClass(const char* module_name, const char* class_name); + struct RClass* GetClass(const char* class_name); + struct RClass* GetClass(const char* module_name, const char* class_name); + + // Utility for binding instance method. + void BindInstanceMethod(const char* class_name, const char* method_name, + mrb_value original_func_v, + mrb_value (*binder_func)(mrb_state*, mrb_value)); + void BindInstanceMethod(const char* module_name, + const char* class_name, const char* method_name, + mrb_value original_func_v, + mrb_value (*binder_func)(mrb_state*, mrb_value)); + + // Mimic mruby API. + // TODO: Send pull request to the official mruby repository. + void + mrb_define_class_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p); + + mrb_state* mrb_; + RClass* mod_; + mrb_value avoid_gc_table_; + int arena_index_; +}; + +MrubyRef load_string(mrb_state* mrb, std::string code); + +} // namespace mrubybind + +#endif diff --git a/mrubybind.inc b/mrubybind.inc index d930896..563bba8 100644 --- a/mrubybind.inc +++ b/mrubybind.inc @@ -1,13 +1,15 @@ // This file is generated from gen_template.rb -#define ARG(i) Type::get(args[i]) -#define CHECK(i) Type::check(args[i]) +#define ARG(mrb, i) Type::get(mrb, args[i]) +#define CHECK(i) {if(!Type::check(args[i])) return RAISE(i);} +#define RAISE(i) raise(mrb, i, Type::TYPE_NAME, args[i]) // void f(void); template<> struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 0); - void (*fp)(void) = (void (*)(void))p; + static const int NPARAM = 0; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(mrb);(void)(args);(void)(narg); + void (*fp)(void) = (void (*)(void))func_ptr; fp(); return mrb_nil_value(); } @@ -16,34 +18,56 @@ struct Binder { // R f(void); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 0); - R (*fp)(void) = (R (*)(void))p; + static const int NPARAM = 0; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(mrb);(void)(args);(void)(narg); + R (*fp)(void) = (R (*)(void))func_ptr; R result = fp(); return Type::ret(mrb, result); } }; -// class C { void f(P0) }; +// C* ctor(void); +template +struct ClassBinder { + static const int NPARAM = 0; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(mrb);(void)(args);(void)(narg); + if(new_func_ptr){ + C* (*ctor)(void) = (C* (*)(void))new_func_ptr; + C* instance = ctor(); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(void) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 0); +struct ClassBinder { + static const int NPARAM = 0; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(mrb);(void)(args);(void)(narg); + C* instance = static_cast(DATA_PTR(self)); typedef void (C::*M)(void); - M method = *(M*)p; - (((C*)o)->*method)(); + M mp = *(M*)method_pptr; + (instance->*mp)(); return mrb_nil_value(); } }; -// class C { R f(P0) }; +// class C { R f(void) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 0); +struct ClassBinder { + static const int NPARAM = 0; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(mrb);(void)(args);(void)(narg); + C* instance = static_cast(DATA_PTR(self)); typedef R (C::*M)(void); - M method = *(M*)p; - R result = (((C*)o)->*method)(); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(); return Type::ret(mrb, result); } }; @@ -51,10 +75,11 @@ struct Binder { // void f(P0); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 1);ASSERT(CHECK(0)); - void (*fp)(P0) = (void (*)(P0))p; - fp(ARG(0)); + static const int NPARAM = 1; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); + void (*fp)(P0) = (void (*)(P0))func_ptr; + fp(ARG(mrb, 0)); return mrb_nil_value(); } }; @@ -62,34 +87,56 @@ struct Binder { // R f(P0); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 1); ASSERT(CHECK(0)); - R (*fp)(P0) = (R (*)(P0))p; - R result = fp(ARG(0)); + static const int NPARAM = 1; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); + R (*fp)(P0) = (R (*)(P0))func_ptr; + R result = fp(ARG(mrb, 0)); return Type::ret(mrb, result); } }; +// C* ctor(P0); +template +struct ClassBinder { + static const int NPARAM = 1; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); + if(new_func_ptr){ + C* (*ctor)(P0) = (C* (*)(P0))new_func_ptr; + C* instance = ctor(ARG(mrb, 0)); + DATA_PTR(self) = instance; + } + return self; + } +}; + // class C { void f(P0) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 1);ASSERT(CHECK(0)); +struct ClassBinder { + static const int NPARAM = 1; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); + C* instance = static_cast(DATA_PTR(self)); typedef void (C::*M)(P0); - M method = *(M*)p; - (((C*)o)->*method)(ARG(0)); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0)); return mrb_nil_value(); } }; // class C { R f(P0) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 1);ASSERT(CHECK(0)); +struct ClassBinder { + static const int NPARAM = 1; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); + C* instance = static_cast(DATA_PTR(self)); typedef R (C::*M)(P0); - M method = *(M*)p; - R result = (((C*)o)->*method)(ARG(0)); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0)); return Type::ret(mrb, result); } }; @@ -97,10 +144,11 @@ struct Binder { // void f(P0, P1); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 2);ASSERT(CHECK(0)); ASSERT(CHECK(1)); - void (*fp)(P0, P1) = (void (*)(P0, P1))p; - fp(ARG(0), ARG(1)); + static const int NPARAM = 2; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); + void (*fp)(P0, P1) = (void (*)(P0, P1))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1)); return mrb_nil_value(); } }; @@ -108,34 +156,56 @@ struct Binder { // R f(P0, P1); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 2); ASSERT(CHECK(0)); ASSERT(CHECK(1)); - R (*fp)(P0, P1) = (R (*)(P0, P1))p; - R result = fp(ARG(0), ARG(1)); + static const int NPARAM = 2; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); + R (*fp)(P0, P1) = (R (*)(P0, P1))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1)); return Type::ret(mrb, result); } }; -// class C { void f(P0) }; +// C* ctor(P0, P1); +template +struct ClassBinder { + static const int NPARAM = 2; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); + if(new_func_ptr){ + C* (*ctor)(P0, P1) = (C* (*)(P0, P1))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 2);ASSERT(CHECK(0)); ASSERT(CHECK(1)); +struct ClassBinder { + static const int NPARAM = 2; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); + C* instance = static_cast(DATA_PTR(self)); typedef void (C::*M)(P0, P1); - M method = *(M*)p; - (((C*)o)->*method)(ARG(0), ARG(1)); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1)); return mrb_nil_value(); } }; -// class C { R f(P0) }; +// class C { R f(P0, P1) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 2);ASSERT(CHECK(0)); ASSERT(CHECK(1)); +struct ClassBinder { + static const int NPARAM = 2; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); + C* instance = static_cast(DATA_PTR(self)); typedef R (C::*M)(P0, P1); - M method = *(M*)p; - R result = (((C*)o)->*method)(ARG(0), ARG(1)); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1)); return Type::ret(mrb, result); } }; @@ -143,10 +213,11 @@ struct Binder { // void f(P0, P1, P2); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 3);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); - void (*fp)(P0, P1, P2) = (void (*)(P0, P1, P2))p; - fp(ARG(0), ARG(1), ARG(2)); + static const int NPARAM = 3; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); + void (*fp)(P0, P1, P2) = (void (*)(P0, P1, P2))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); return mrb_nil_value(); } }; @@ -154,34 +225,56 @@ struct Binder { // R f(P0, P1, P2); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 3); ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); - R (*fp)(P0, P1, P2) = (R (*)(P0, P1, P2))p; - R result = fp(ARG(0), ARG(1), ARG(2)); + static const int NPARAM = 3; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); + R (*fp)(P0, P1, P2) = (R (*)(P0, P1, P2))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); return Type::ret(mrb, result); } }; -// class C { void f(P0) }; +// C* ctor(P0, P1, P2); template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 3);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); +struct ClassBinder { + static const int NPARAM = 3; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); + if(new_func_ptr){ + C* (*ctor)(P0, P1, P2) = (C* (*)(P0, P1, P2))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2) }; +template +struct ClassBinder { + static const int NPARAM = 3; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); + C* instance = static_cast(DATA_PTR(self)); typedef void (C::*M)(P0, P1, P2); - M method = *(M*)p; - (((C*)o)->*method)(ARG(0), ARG(1), ARG(2)); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); return mrb_nil_value(); } }; -// class C { R f(P0) }; +// class C { R f(P0, P1, P2) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 3);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); +struct ClassBinder { + static const int NPARAM = 3; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); + C* instance = static_cast(DATA_PTR(self)); typedef R (C::*M)(P0, P1, P2); - M method = *(M*)p; - R result = (((C*)o)->*method)(ARG(0), ARG(1), ARG(2)); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2)); return Type::ret(mrb, result); } }; @@ -189,10 +282,11 @@ struct Binder { // void f(P0, P1, P2, P3); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 4);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); - void (*fp)(P0, P1, P2, P3) = (void (*)(P0, P1, P2, P3))p; - fp(ARG(0), ARG(1), ARG(2), ARG(3)); + static const int NPARAM = 4; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); + void (*fp)(P0, P1, P2, P3) = (void (*)(P0, P1, P2, P3))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); return mrb_nil_value(); } }; @@ -200,34 +294,56 @@ struct Binder { // R f(P0, P1, P2, P3); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 4); ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); - R (*fp)(P0, P1, P2, P3) = (R (*)(P0, P1, P2, P3))p; - R result = fp(ARG(0), ARG(1), ARG(2), ARG(3)); + static const int NPARAM = 4; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); + R (*fp)(P0, P1, P2, P3) = (R (*)(P0, P1, P2, P3))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); return Type::ret(mrb, result); } }; -// class C { void f(P0) }; +// C* ctor(P0, P1, P2, P3); template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 4);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); +struct ClassBinder { + static const int NPARAM = 4; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); + if(new_func_ptr){ + C* (*ctor)(P0, P1, P2, P3) = (C* (*)(P0, P1, P2, P3))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3) }; +template +struct ClassBinder { + static const int NPARAM = 4; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); + C* instance = static_cast(DATA_PTR(self)); typedef void (C::*M)(P0, P1, P2, P3); - M method = *(M*)p; - (((C*)o)->*method)(ARG(0), ARG(1), ARG(2), ARG(3)); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); return mrb_nil_value(); } }; -// class C { R f(P0) }; +// class C { R f(P0, P1, P2, P3) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 4);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); +struct ClassBinder { + static const int NPARAM = 4; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); + C* instance = static_cast(DATA_PTR(self)); typedef R (C::*M)(P0, P1, P2, P3); - M method = *(M*)p; - R result = (((C*)o)->*method)(ARG(0), ARG(1), ARG(2), ARG(3)); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3)); return Type::ret(mrb, result); } }; @@ -235,10 +351,11 @@ struct Binder { // void f(P0, P1, P2, P3, P4); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 5);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); ASSERT(CHECK(4)); - void (*fp)(P0, P1, P2, P3, P4) = (void (*)(P0, P1, P2, P3, P4))p; - fp(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4)); + static const int NPARAM = 5; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); + void (*fp)(P0, P1, P2, P3, P4) = (void (*)(P0, P1, P2, P3, P4))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); return mrb_nil_value(); } }; @@ -246,34 +363,56 @@ struct Binder { // R f(P0, P1, P2, P3, P4); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 5); ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); ASSERT(CHECK(4)); - R (*fp)(P0, P1, P2, P3, P4) = (R (*)(P0, P1, P2, P3, P4))p; - R result = fp(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4)); + static const int NPARAM = 5; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); + R (*fp)(P0, P1, P2, P3, P4) = (R (*)(P0, P1, P2, P3, P4))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); return Type::ret(mrb, result); } }; -// class C { void f(P0) }; +// C* ctor(P0, P1, P2, P3, P4); template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 5);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); ASSERT(CHECK(4)); +struct ClassBinder { + static const int NPARAM = 5; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); + if(new_func_ptr){ + C* (*ctor)(P0, P1, P2, P3, P4) = (C* (*)(P0, P1, P2, P3, P4))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4) }; +template +struct ClassBinder { + static const int NPARAM = 5; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); + C* instance = static_cast(DATA_PTR(self)); typedef void (C::*M)(P0, P1, P2, P3, P4); - M method = *(M*)p; - (((C*)o)->*method)(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4)); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); return mrb_nil_value(); } }; -// class C { R f(P0) }; +// class C { R f(P0, P1, P2, P3, P4) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 5);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); ASSERT(CHECK(4)); +struct ClassBinder { + static const int NPARAM = 5; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); + C* instance = static_cast(DATA_PTR(self)); typedef R (C::*M)(P0, P1, P2, P3, P4); - M method = *(M*)p; - R result = (((C*)o)->*method)(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4)); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4)); return Type::ret(mrb, result); } }; @@ -281,10 +420,11 @@ struct Binder { // void f(P0, P1, P2, P3, P4, P5); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 6);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); ASSERT(CHECK(4)); ASSERT(CHECK(5)); - void (*fp)(P0, P1, P2, P3, P4, P5) = (void (*)(P0, P1, P2, P3, P4, P5))p; - fp(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4), ARG(5)); + static const int NPARAM = 6; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); + void (*fp)(P0, P1, P2, P3, P4, P5) = (void (*)(P0, P1, P2, P3, P4, P5))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); return mrb_nil_value(); } }; @@ -292,34 +432,332 @@ struct Binder { // R f(P0, P1, P2, P3, P4, P5); template struct Binder { - static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) { - ASSERT(narg == 6); ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); ASSERT(CHECK(4)); ASSERT(CHECK(5)); - R (*fp)(P0, P1, P2, P3, P4, P5) = (R (*)(P0, P1, P2, P3, P4, P5))p; - R result = fp(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4), ARG(5)); + static const int NPARAM = 6; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); + R (*fp)(P0, P1, P2, P3, P4, P5) = (R (*)(P0, P1, P2, P3, P4, P5))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); return Type::ret(mrb, result); } }; -// class C { void f(P0) }; +// C* ctor(P0, P1, P2, P3, P4, P5); template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 6);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); ASSERT(CHECK(4)); ASSERT(CHECK(5)); +struct ClassBinder { + static const int NPARAM = 6; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); + if(new_func_ptr){ + C* (*ctor)(P0, P1, P2, P3, P4, P5) = (C* (*)(P0, P1, P2, P3, P4, P5))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5) }; +template +struct ClassBinder { + static const int NPARAM = 6; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); + C* instance = static_cast(DATA_PTR(self)); typedef void (C::*M)(P0, P1, P2, P3, P4, P5); - M method = *(M*)p; - (((C*)o)->*method)(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4), ARG(5)); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); return mrb_nil_value(); } }; -// class C { R f(P0) }; +// class C { R f(P0, P1, P2, P3, P4, P5) }; template -struct Binder { - static mrb_value call(mrb_state* mrb, void* o, void* p, mrb_value* args, int narg) { - ASSERT(narg == 6);ASSERT(CHECK(0)); ASSERT(CHECK(1)); ASSERT(CHECK(2)); ASSERT(CHECK(3)); ASSERT(CHECK(4)); ASSERT(CHECK(5)); +struct ClassBinder { + static const int NPARAM = 6; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); + C* instance = static_cast(DATA_PTR(self)); typedef R (C::*M)(P0, P1, P2, P3, P4, P5); - M method = *(M*)p; - R result = (((C*)o)->*method)(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4), ARG(5)); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5)); + return Type::ret(mrb, result); + } +}; + +// void f(P0, P1, P2, P3, P4, P5, P6); +template +struct Binder { + static const int NPARAM = 7; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); + void (*fp)(P0, P1, P2, P3, P4, P5, P6) = (void (*)(P0, P1, P2, P3, P4, P5, P6))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6); +template +struct Binder { + static const int NPARAM = 7; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); + R (*fp)(P0, P1, P2, P3, P4, P5, P6) = (R (*)(P0, P1, P2, P3, P4, P5, P6))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6); +template +struct ClassBinder { + static const int NPARAM = 7; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); + if(new_func_ptr){ + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6) = (C* (*)(P0, P1, P2, P3, P4, P5, P6))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6) }; +template +struct ClassBinder { + static const int NPARAM = 7; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); + C* instance = static_cast(DATA_PTR(self)); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6) }; +template +struct ClassBinder { + static const int NPARAM = 7; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); + C* instance = static_cast(DATA_PTR(self)); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6)); + return Type::ret(mrb, result); + } +}; + +// void f(P0, P1, P2, P3, P4, P5, P6, P7); +template +struct Binder { + static const int NPARAM = 8; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7); +template +struct Binder { + static const int NPARAM = 8; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7); +template +struct ClassBinder { + static const int NPARAM = 8; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); + if(new_func_ptr){ + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7) }; +template +struct ClassBinder { + static const int NPARAM = 8; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); + C* instance = static_cast(DATA_PTR(self)); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7) }; +template +struct ClassBinder { + static const int NPARAM = 8; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); + C* instance = static_cast(DATA_PTR(self)); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7)); + return Type::ret(mrb, result); + } +}; + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8); +template +struct Binder { + static const int NPARAM = 9; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8); +template +struct Binder { + static const int NPARAM = 9; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8); +template +struct ClassBinder { + static const int NPARAM = 9; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); + if(new_func_ptr){ + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8) }; +template +struct ClassBinder { + static const int NPARAM = 9; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); + C* instance = static_cast(DATA_PTR(self)); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8) }; +template +struct ClassBinder { + static const int NPARAM = 9; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); + C* instance = static_cast(DATA_PTR(self)); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8)); + return Type::ret(mrb, result); + } +}; + +// void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); +template +struct Binder { + static const int NPARAM = 10; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); (void)(narg); CHECK(9); + void (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) = (void (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9))func_ptr; + fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + return mrb_nil_value(); + } +}; + +// R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); +template +struct Binder { + static const int NPARAM = 10; + static mrb_value call(mrb_state* mrb, void* func_ptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); (void)(narg); CHECK(9); + R (*fp)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) = (R (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9))func_ptr; + R result = fp(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + return Type::ret(mrb, result); + } +}; + +// C* ctor(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); +template +struct ClassBinder { + static const int NPARAM = 10; + static mrb_value ctor(mrb_state* mrb, mrb_value self, void* new_func_ptr, mrb_value* args, int narg) { + DATA_TYPE(self) = &ClassBinder::type_info; + DATA_PTR(self) = NULL; + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); (void)(narg); CHECK(9); + if(new_func_ptr){ + C* (*ctor)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) = (C* (*)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9))new_func_ptr; + C* instance = ctor(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + DATA_PTR(self) = instance; + } + return self; + } +}; + +// class C { void f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) }; +template +struct ClassBinder { + static const int NPARAM = 10; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); (void)(narg); CHECK(9); + C* instance = static_cast(DATA_PTR(self)); + typedef void (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); + M mp = *(M*)method_pptr; + (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); + return mrb_nil_value(); + } +}; + +// class C { R f(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) }; +template +struct ClassBinder { + static const int NPARAM = 10; + static mrb_value call(mrb_state* mrb, mrb_value self, void* method_pptr, mrb_value* args, int narg) { + (void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); (void)(narg); CHECK(9); + C* instance = static_cast(DATA_PTR(self)); + typedef R (C::*M)(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9); + M mp = *(M*)method_pptr; + R result = (instance->*mp)(ARG(mrb, 0), ARG(mrb, 1), ARG(mrb, 2), ARG(mrb, 3), ARG(mrb, 4), ARG(mrb, 5), ARG(mrb, 6), ARG(mrb, 7), ARG(mrb, 8), ARG(mrb, 9)); return Type::ret(mrb, result); } }; diff --git a/mrubybind_call_generated.h b/mrubybind_call_generated.h new file mode 100644 index 0000000..beee1d0 --- /dev/null +++ b/mrubybind_call_generated.h @@ -0,0 +1,77 @@ +// This file is generated from gen_template.rb +#define ARG(mrb, i) Type::get(mrb, args[i]) +#define CHECK(i) {if(!Type::check(mrb, args[i])) return RAISE(i);} +#define RAISE(i) raise(mrb, i, Type::TYPE_NAME, args[i]) + + + templateMrubyRef call(std::string name, P0 a0){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 1, Type::ret(mrb, a0))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 2, Type::ret(mrb, a0), Type::ret(mrb, a1))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1, P2 a2){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 3, Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1, P2 a2, P3 a3){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 4, Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1, P2 a2, P3 a3, P4 a4){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 5, Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 6, Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 7, Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 8, Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 9, Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7), Type::ret(mrb, a8))); + } + + + templateMrubyRef call(std::string name, P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9){ + MrubyArenaStore mas(mrb); + //(void)(narg); CHECK(0); (void)(narg); CHECK(1); (void)(narg); CHECK(2); (void)(narg); CHECK(3); (void)(narg); CHECK(4); (void)(narg); CHECK(5); (void)(narg); CHECK(6); (void)(narg); CHECK(7); (void)(narg); CHECK(8); (void)(narg); CHECK(9); + return MrubyRef(mrb, mrb_funcall(mrb, *(this->v.get()), name.c_str(), 10, Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7), Type::ret(mrb, a8), Type::ret(mrb, a9))); + } + +#undef ARG +#undef CHECK diff --git a/mrubybind_types.h b/mrubybind_types.h deleted file mode 100644 index 4b6f255..0000000 --- a/mrubybind_types.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef __MRUBYBIND_TYPES_H__ -#define __MRUBYBIND_TYPES_H__ - -#include -#include -#include - -#include -#define ASSERT(expr) assert(expr) - -namespace mrubybind { - -//=========================================================================== -// C <-> mruby type converter. - -template -struct Type { - //static int check(mrb_value v) = 0; - //static int get(mrb_value v) = 0; - //static mrb_value ret(mrb_state*, int i) = 0; -}; - -// Fixnum -template<> -struct Type { - static int check(mrb_value v) { return mrb_fixnum_p(v); } - static int get(mrb_value v) { return mrb_fixnum(v); } - static mrb_value ret(mrb_state*, int i) { return mrb_fixnum_value(i); } -}; - -// float -template<> -struct Type { - static int check(mrb_value v) { return mrb_float_p(v); } - static float get(mrb_value v) { return mrb_float(v); } - static mrb_value ret(mrb_state*, float f) { return mrb_float_value(f); } -}; - -// double -template<> -struct Type { - static int check(mrb_value v) { return mrb_float_p(v); } - static double get(mrb_value v) { return mrb_float(v); } - static mrb_value ret(mrb_state*, double f) { return mrb_float_value(f); } -}; - -// String -template<> -struct Type { - static int check(mrb_value v) { return mrb_string_p(v); } - static const char* get(mrb_value v) { return RSTRING_PTR(v); } - static mrb_value ret(mrb_state* mrb, const char* s) { return mrb_str_new_cstr(mrb, s); } -}; - -template<> -struct Type { - static int check(mrb_value v) { return mrb_string_p(v); } - static const std::string get(mrb_value v) { return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } - static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } -}; - -template<> -struct Type { - static int check(mrb_value v) { return mrb_string_p(v); } - static const std::string get(mrb_value v) { return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } - static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } -}; - -template<> -struct Type { - static int check(mrb_value v) { return mrb_string_p(v); } - static const std::string get(mrb_value v) { return std::string(RSTRING_PTR(v), RSTRING_LEN(v)); } - static mrb_value ret(mrb_state* mrb, const std::string& s) { return mrb_str_new(mrb, s.c_str(), s.size()); } -}; - -// Boolean -template<> -struct Type { - static int check(mrb_value v) { return 1; } - static bool get(mrb_value v) { return mrb_test(v); } - static mrb_value ret(mrb_state* mrb, bool b) { return b ? mrb_true_value() : mrb_false_value(); } -}; - -// Raw pointer -template<> -struct Type { - static int check(mrb_value v) { return mrb_voidp_p(v); } - static void* get(mrb_value v) { return mrb_voidp(v); } - static mrb_value ret(mrb_state* mrb, void* p) { return mrb_voidp_value(p); } -}; - -//=========================================================================== -// Binder - -// Template class for Binder. -// Binder template class is specialized with type. -template -struct Binder { - //static mrb_value call(mrb_state* mrb, void* p, mrb_value* args, int narg) = 0; -}; - -// Includes generated template specialization. -#include "mrubybind.inc" - -} // namespace mrubybind - -#undef ASSERT - -#endif diff --git a/mrubybind_types_generated.h b/mrubybind_types_generated.h new file mode 100644 index 0000000..cf01129 --- /dev/null +++ b/mrubybind_types_generated.h @@ -0,0 +1,397 @@ +// This file is generated from gen_template.rb +#define ARG(mrb, i) Type::get(mrb, args[i]) +#define CHECK(i) {if(!Type::check(mrb, args[i])) return RAISE(i);} +#define RAISE(i) raise(mrb, i, Type::TYPE_NAME, args[i]) + + +// callback R(P0) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 1, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0)}; + mrb_yield_argv(mrb, v, 1, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 2, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1)}; + mrb_yield_argv(mrb, v, 2, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1, P2) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 3, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1, P2) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2)}; + mrb_yield_argv(mrb, v, 3, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1, P2, P3) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 4, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1, P2, P3) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3)}; + mrb_yield_argv(mrb, v, 4, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1, P2, P3, P4) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 5, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1, P2, P3, P4) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4)}; + mrb_yield_argv(mrb, v, 5, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1, P2, P3, P4, P5) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 6, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1, P2, P3, P4, P5) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5)}; + mrb_yield_argv(mrb, v, 6, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1, P2, P3, P4, P5, P6) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 7, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1, P2, P3, P4, P5, P6) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6)}; + mrb_yield_argv(mrb, v, 7, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1, P2, P3, P4, P5, P6, P7) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 8, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1, P2, P3, P4, P5, P6, P7) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7)}; + mrb_yield_argv(mrb, v, 8, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1, P2, P3, P4, P5, P6, P7, P8) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7), Type::ret(mrb, a8)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 9, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1, P2, P3, P4, P5, P6, P7, P8) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7), Type::ret(mrb, a8)}; + mrb_yield_argv(mrb, v, 9, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + + +// callback R(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7), Type::ret(mrb, a8), Type::ret(mrb, a9)}; + return Type::get(mrb, mrb_yield_argv(mrb, v, 10, a)); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +// callback void(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) +template +struct Type > : public TypeFuncBase { + static int check(mrb_state*, mrb_value v) { return mrb_type(v) == MRB_TT_PROC; } + static FuncPtr get(mrb_state* mrb, mrb_value v) { + Deleter > d = set_avoid_gc >(mrb, v); + return make_FuncPtr(d, [=](P0 a0, P1 a1, P2 a2, P3 a3, P4 a4, P5 a5, P6 a6, P7 a7, P8 a8, P9 a9){ + MrubyArenaStore mas(mrb); + mrb_value a[] = {Type::ret(mrb, a0), Type::ret(mrb, a1), Type::ret(mrb, a2), Type::ret(mrb, a3), Type::ret(mrb, a4), Type::ret(mrb, a5), Type::ret(mrb, a6), Type::ret(mrb, a7), Type::ret(mrb, a8), Type::ret(mrb, a9)}; + mrb_yield_argv(mrb, v, 10, a); + }); + } + static mrb_value ret(mrb_state* mrb, FuncPtr p) { + // don't call. + throw std::runtime_error("don't call Type >::ret"); + (void)mrb; (void)p; return mrb_nil_value(); + } +}; + +#undef ARG +#undef CHECK diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..689dd74 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,73 @@ + +INC=-I $(MRUBY)/include -I .. +LIB=-L $(MRUBY)/build/host/lib -lmruby + +MRUBYBIND_SRCDIR=.. +MRUBYBIND_OBJ=mrubybind.o + +SRCS=$(wildcard *.cc) +EXES=$(SRCS:%.cc=%) + +CXX?= CXX +CXXFLAGS=-Wall -Wextra -Werror -g -std=c++11 -DEXIT_SUCCESS=0 -DEXIT_FAILURE=1 + +all: $(EXES) + +clean: + rm -rf *.o $(EXES) + +test: $(EXES) + ./test.sh + +%.o: %.cc + $(CXX) -c -o $@ $(INC) $(CXXFLAGS) $< + +mrubybind.o: $(MRUBYBIND_SRCDIR)/mrubybind.cc + $(CXX) -c -o $@ $(INC) $(CXXFLAGS) $< + +void: void.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +int: int.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +float: float.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +string: string.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +cptr: cptr.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +class: class.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +module: module.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +wrong_type: wrong_type.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +wrong_arg_num: wrong_arg_num.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +class_value: class_value.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +mruby_ref: mruby_ref.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +many_bind: many_bind.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +class_convert: class_convert.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +reference: reference.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +avoid_gc: avoid_gc.o $(MRUBYBIND_OBJ) + $(CXX) -o $@ $^ $(LIB) $(INC) $(CXXFLAGS) + +# diff --git a/test/avoid_gc.cc b/test/avoid_gc.cc new file mode 100644 index 0000000..6868322 --- /dev/null +++ b/test/avoid_gc.cc @@ -0,0 +1,126 @@ + +#include +#include +#include "mrubybind.h" + +#include +using namespace std; + +typedef mrubybind::FuncPtr Func; + +Func f0; +Func f1; +Func f2; + +void set_f0(Func f) +{ + f0 = f; +} + +void set_f1(Func f) +{ + f1 = f; +} + +void set_f2(Func f) +{ + f2 = f; +} + +void clear_f0() +{ + f0.reset(); +} + +void clear_f1() +{ + f1.reset(); +} + +void clear_f2() +{ + f2.reset(); +} + +void call_f2() +{ + f2.func()(); +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("set_f0", set_f0); + b.bind("set_f1", set_f1); + b.bind("set_f2", set_f2); + b.bind("clear_f0", clear_f0); + b.bind("clear_f1", clear_f1); + b.bind("clear_f2", clear_f2); + b.bind("call_f2", call_f2); + } + + int result_code = EXIT_SUCCESS; + mrb_load_string(mrb, + "puts \"start avoid_gc\"\n" + "def f\n" + " fa = Proc.new do\n" + " puts \"called!\"\n" + " end\n" + " set_f0 fa\n" + " set_f1 fa\n" + " set_f2 fa\n" + "end\n" + "f\n" + "clear_f0\n" + "clear_f1\n" + "GC.start\n" + "call_f2\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + mrb_close(mrb); + return result_code; + } + + mrb_load_string(mrb, + "puts \"start avoid_gc 2\"\n" + "def f(&block)\n" + " fa = Proc.new do\n" + " clear_f2\n" + " GC.start\n" + " puts \"called!\"\n" + " yield\n" + " end\n" + " set_f0 fa\n" + " set_f1 fa\n" + " set_f2 fa\n" + " fa = nil\n" + "end\n" + "def g\n" + " f do\n" + " puts \"block called!\"\n" + " end\n" + "end\n" + "g\n" + "clear_f0\n" + "clear_f1\n" + "GC.start\n" + "call_f2\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + mrb_close(mrb); + return result_code; + } + + mrb_close(mrb); + return result_code; +} + + + + diff --git a/test/class.cc b/test/class.cc new file mode 100644 index 0000000..5fd62b7 --- /dev/null +++ b/test/class.cc @@ -0,0 +1,59 @@ +// Simple usage for binding C++ class. + +#include +#include +#include "mrubybind.h" + +#include +using namespace std; + +class Foo { +public: + Foo(int x) : x_(x) { + cout << "Foo::ctor(" << x << ")" << endl; + } + virtual ~Foo() { + cout << "Foo::dtor()" << endl; + } + int bar(int y) { + return x_ + y; + } + static int baz(int z) { + return z * z; + } + +private: + int x_; +}; + +Foo* new_foo(int x) { + return new Foo(x); +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind_class("Foo", new_foo); + b.bind_instance_method("Foo", "bar", &Foo::bar); + b.bind_static_method("Foo", "baz", &Foo::baz); + } + if (mrb_gc_arena_save(mrb) != 0) { + fprintf(stderr, "Arena increased!\n"); + return EXIT_FAILURE; + } + + mrb_load_string(mrb, + "foo = Foo.new(123)\n" + "p foo.bar(567)\n" + "p Foo.baz(9999)" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + return EXIT_FAILURE; + } + + mrb_close(mrb); + return EXIT_SUCCESS; +} diff --git a/test/class_convert.cc b/test/class_convert.cc new file mode 100644 index 0000000..971f9d6 --- /dev/null +++ b/test/class_convert.cc @@ -0,0 +1,84 @@ +#include +#include +#include "mrubybind.h" + +#include +using namespace std; + +class TA{ + int num; +public: + TA(){ + num = 1; + } + + virtual int get_num(){ + return num; + } + +}; + +class TB : public TA{ + int num2; +public: + TB(){ + num2 = 2; + } + + virtual int get_num(){ + return num2; + } + +}; + +std::shared_ptr create_a() +{ + return std::make_shared(); +} + +std::shared_ptr create_b() +{ + return std::make_shared(); +} + +int get_num_a(std::shared_ptr a) +{ + return a->get_num(); +} + +int get_num_b(std::shared_ptr b) +{ + return b->get_num(); +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind_class >("TA"); + b.bind_class >("TB"); + b.bind_static_method("TA", "create", create_a); + b.bind_static_method("TB", "create", create_b); + b.bind_static_method("TA", "get_num", get_num_a); + b.bind_static_method("TB", "get_num", get_num_b); + b.add_convertable("TA", "TB"); + } + + int result_code = EXIT_SUCCESS; + mrb_load_string(mrb, + "a = TA.create\n" + "b = TB.create\n" + "puts \"TA -> a = #{TA.get_num a}\"\n" + "puts \"TB -> b = #{TB.get_num b}\"\n" + "puts \"TA -> b = #{TA.get_num b}\"\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + } + + mrb_close(mrb); + return result_code; +} + diff --git a/test/class_value.cc b/test/class_value.cc new file mode 100644 index 0000000..f00ee5b --- /dev/null +++ b/test/class_value.cc @@ -0,0 +1,125 @@ + + +#include +#include +#include "mrubybind.h" + +#include +using namespace std; + +class ClassValue{ +public: + int a; + mrubybind::FuncPtr block; + + ClassValue(){ + std::cout << "ClassValue construct.\n"; + a = 7; + } + + ~ClassValue(){ + std::cout << "ClassValue destruct.\n"; + } + + void decriment(){ + a--; + } + + void set_block(mrubybind::FuncPtr block){ + this->block = block; + } + + std::string call_block(){ + return block.func()(a, "test"); + } +}; + +std::shared_ptr create_class_value() +{ + return std::shared_ptr(new ClassValue()); +} + +void class_value_increment(std::shared_ptr cv) +{ + cv->a++; +} + +int class_value_get_a(std::shared_ptr cv) +{ + return cv->a; +} + +void class_value_decriment(std::shared_ptr cv) +{ + cv->decriment(); +} + +std::weak_ptr convert_to_weak_class_value(std::shared_ptr cv){ + return cv; +} + +int weak_class_value_get_a(std::weak_ptr cv) +{ + if(auto ptr = cv.lock()){ + return ptr->a; + } + return 0; +} + +void class_value_set_block(std::shared_ptr cv, mrubybind::FuncPtr block) +{ + cv->set_block(block); +} + +std::string class_value_call_block(std::shared_ptr cv) +{ + return cv->call_block(); +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("create_class_value", create_class_value); + b.bind_class >("ClassValue"); + b.bind_class >("WeakClassValue"); + b.bind("class_value_increment", class_value_increment); + b.bind("class_value_get_a", class_value_get_a); + b.bind_custom_method(NULL, "ClassValue", "decriment", class_value_decriment); + b.bind("convert_to_weak_class_value", convert_to_weak_class_value); + b.bind("weak_class_value_get_a", weak_class_value_get_a); + b.bind_custom_method("ClassValue", "set_block", class_value_set_block); + b.bind_custom_method("ClassValue", "call_block", class_value_call_block); + } + + int result_code = EXIT_SUCCESS; + mrb_load_string(mrb, + "puts \"start ClassPointerTest\"\n" + "cv = create_class_value\n" + "puts \"cv -> #{class_value_get_a(cv)}\"\n" + "class_value_increment(cv)\n" + "puts \"cv -> #{class_value_get_a cv}\"\n" + "cv.decriment\n" + "puts \"cv -> #{class_value_get_a cv}\"\n" + "cv.set_block do |a0, a1|\n" + " a1.to_s + a0.to_s\n" + "end\n" + "puts \"cv.call_block -> #{cv.call_block}\"\n" + "wk = convert_to_weak_class_value cv\n" + "puts \"wk->#{weak_class_value_get_a wk}\"\n" + "cv = nil\n" + "puts \"GC\"\n" + "GC.start\n" + "puts \"wk->#{weak_class_value_get_a wk}\"\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + } + + mrb_close(mrb); + return result_code; +} + + diff --git a/test/cptr.cc b/test/cptr.cc new file mode 100644 index 0000000..e805881 --- /dev/null +++ b/test/cptr.cc @@ -0,0 +1,37 @@ +#include +#include +#include "mrubybind.h" +#include + +void* myopen() { + return stdout; +} + +void mywrite(void* fp, const char* string) { + fwrite(string, 1, strlen(string), (FILE*)fp); +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("myopen", myopen); + b.bind("mywrite", mywrite); + } + if (mrb_gc_arena_save(mrb) != 0) { + fprintf(stderr, "Arena increased!\n"); + return EXIT_FAILURE; + } + + mrb_load_string(mrb, + "f = myopen()\n" + "mywrite(f, 'cptr test')"); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + return EXIT_FAILURE; + } + + mrb_close(mrb); + return EXIT_SUCCESS; +} diff --git a/test/float.cc b/test/float.cc new file mode 100644 index 0000000..8c1f91c --- /dev/null +++ b/test/float.cc @@ -0,0 +1,30 @@ +#include +#include +#include "mrubybind.h" +#include + +double mul(float x, double y) { + return x * y; +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("mul", mul); + } + if (mrb_gc_arena_save(mrb) != 0) { + fprintf(stderr, "Arena increased!\n"); + return EXIT_FAILURE; + } + + mrb_load_string(mrb, "puts mul(12.0, 34.0)"); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + return EXIT_FAILURE; + } + + mrb_close(mrb); + return EXIT_SUCCESS; +} diff --git a/test/int.cc b/test/int.cc new file mode 100644 index 0000000..9d0ad23 --- /dev/null +++ b/test/int.cc @@ -0,0 +1,30 @@ +#include +#include +#include "mrubybind.h" +#include + +int square(int x) { + return x * x; +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("square", square); + } + if (mrb_gc_arena_save(mrb) != 0) { + fprintf(stderr, "Arena increased!\n"); + return EXIT_FAILURE; + } + + mrb_load_string(mrb, "puts square(1111)"); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + return EXIT_FAILURE; + } + + mrb_close(mrb); + return EXIT_SUCCESS; +} diff --git a/test/many_bind.cc b/test/many_bind.cc new file mode 100644 index 0000000..509efac --- /dev/null +++ b/test/many_bind.cc @@ -0,0 +1,127 @@ + +#include +#include +#include "mrubybind.h" + +#include +using namespace std; + +class ClassValue{ +public: + int a; + mrubybind::FuncPtr block; + + ClassValue(){ + std::cout << "ClassValue construct.\n"; + a = 7; + } + + ~ClassValue(){ + std::cout << "ClassValue destruct.\n"; + } + + void decriment(){ + a--; + } + + void set_block(mrubybind::FuncPtr block){ + this->block = block; + } + + std::string call_block(){ + return block.func()(a, "test"); + } +}; + +std::shared_ptr create_class_value() +{ + return std::shared_ptr(new ClassValue()); +} + +void class_value_increment(std::shared_ptr cv) +{ + cv->a++; +} + +int class_value_get_a(std::shared_ptr cv) +{ + return cv->a; +} + +void class_value_decriment(std::shared_ptr cv) +{ + cv->decriment(); +} + +std::weak_ptr convert_to_weak_class_value(std::shared_ptr cv){ + return cv; +} + +int weak_class_value_get_a(std::weak_ptr cv) +{ + if(auto ptr = cv.lock()){ + return ptr->a; + } + return 0; +} + +void class_value_set_block(std::shared_ptr cv, mrubybind::FuncPtr block) +{ + cv->set_block(block); +} + +std::string class_value_call_block(std::shared_ptr cv) +{ + return cv->call_block(); +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + int i; + for(i = 0 ; i < 100 ; i++){ + b.bind("create_class_value", create_class_value); + b.bind_class >("ClassValue"); + b.bind_class >("WeakClassValue"); + b.bind("class_value_increment", class_value_increment); + b.bind("class_value_get_a", class_value_get_a); + b.bind_custom_method(NULL, "ClassValue", "decriment", class_value_decriment); + b.bind("convert_to_weak_class_value", convert_to_weak_class_value); + b.bind("weak_class_value_get_a", weak_class_value_get_a); + b.bind_custom_method("ClassValue", "set_block", class_value_set_block); + b.bind_custom_method("ClassValue", "call_block", class_value_call_block); + } + + std::cout << "arena_index = " << mrb_gc_arena_save(mrb) << std::endl; + } + + int result_code = EXIT_SUCCESS; + mrb_load_string(mrb, + "puts \"start ClassPointerTest\"\n" + "cv = create_class_value\n" + "puts \"cv -> #{class_value_get_a(cv)}\"\n" + "class_value_increment(cv)\n" + "puts \"cv -> #{class_value_get_a cv}\"\n" + "cv.decriment\n" + "puts \"cv -> #{class_value_get_a cv}\"\n" + "cv.set_block do |a0, a1|\n" + " a1.to_s + a0.to_s\n" + "end\n" + "puts \"cv.call_block -> #{cv.call_block}\"\n" + "wk = convert_to_weak_class_value cv\n" + "puts \"wk->#{weak_class_value_get_a wk}\"\n" + "cv = nil\n" + "puts \"GC\"\n" + "GC.start\n" + "puts \"wk->#{weak_class_value_get_a wk}\"\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + } + + mrb_close(mrb); + return result_code; +} \ No newline at end of file diff --git a/test/module.cc b/test/module.cc new file mode 100644 index 0000000..6fd1e6c --- /dev/null +++ b/test/module.cc @@ -0,0 +1,71 @@ +// Simple usage for binding function under some module. + +#include +#include +#include "mrubybind.h" +#include + + +class ModClass { +public: + int a; + + ModClass(int a) + { + this->a = a; + } +}; + +std::shared_ptr create_mod_class(int a) +{ + return std::shared_ptr(new ModClass(a)); +} + +int mod_class_get_a(std::shared_ptr c) +{ + return c->a; +} + +void modfunc(int v) { + printf("modfunc called: %d\n", v); +} + +int main() { + mrb_state* mrb = mrb_open(); + + RClass* mod = mrb_define_module(mrb, "Mod"); + int arena = mrb_gc_arena_save(mrb); + { + mrubybind::MrubyBind b(mrb, mod); + b.bind("modfunc", modfunc); + b.bind_const("FOO_VALUE", 1234); + + b.bind_class >("Mod::Mod2", "ModClass"); + b.bind_const("Mod", "ModClass", "CNST", 12345); + b.bind_static_method("Mod", "ModClass", "create", create_mod_class); + b.bind_custom_method("Mod", "ModClass", "get_a", mod_class_get_a); + b.bind_const("Mod::Mod2", "ModClass", "CNST", 12345); + b.bind_static_method("Mod::Mod2", "ModClass", "create", create_mod_class); + b.bind_custom_method("Mod::Mod2", "ModClass", "get_a", mod_class_get_a); + } + if (mrb_gc_arena_save(mrb) != arena) { + fprintf(stderr, "Arena increased!\n"); + return EXIT_FAILURE; + } + + mrb_load_string(mrb, "Mod.modfunc(Mod::FOO_VALUE)\n" + "c = Mod::ModClass.create 4\n" + "puts \"Mod::ModClass::CNST #{Mod::Mod2::ModClass::CNST}\"\n" + "puts \"c.get_a #{c.get_a}\"\n" + "c = Mod::Mod2::ModClass.create 4\n" + "puts \"Mod::Mod2::ModClass::CNST #{Mod::Mod2::ModClass::CNST}\"\n" + "puts \"c.get_a #{c.get_a}\"\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + return EXIT_FAILURE; + } + + mrb_close(mrb); + return EXIT_SUCCESS; +} diff --git a/test/mruby_ref.cc b/test/mruby_ref.cc new file mode 100644 index 0000000..c2bbdd8 --- /dev/null +++ b/test/mruby_ref.cc @@ -0,0 +1,51 @@ + +#include +#include +#include "mrubybind.h" + +#include +using namespace std; + +mrubybind::MrubyRef mruby_ref; +mrubybind::MrubyRef mruby_ref_a, mruby_ref_b; + +void set_mruby_ref(mrubybind::MrubyRef r){ + mruby_ref = r; +} + +void set_mruby_ref_pair(mrubybind::MrubyRef a, mrubybind::MrubyRef b){ + mruby_ref_a = a; + mruby_ref_b = b; +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("set_mruby_ref", set_mruby_ref); + b.bind("set_mruby_ref_pair", set_mruby_ref_pair); + } + + int result_code = EXIT_SUCCESS; + mrubybind::load_string(mrb, + "set_mruby_ref \"3test\"\n" + "s = \"aaa\"\n" + "set_mruby_ref_pair s, s\n" + "set_mruby_ref_pair :s, :s\n" + ); + std::cout << "mruby_ref = " << mruby_ref.to_s() << std::endl; + std::cout << "mruby_ref = " << mruby_ref.to_i() << std::endl; + std::cout << "mruby_ref = " << mruby_ref.call("gsub", "te", "toa").to_s() << std::endl; + std::cout << ":a == :a = " << mruby_ref_a.obj_equal(mruby_ref_b) << std::endl; + std::cout << "arena_index = " << mrb_gc_arena_save(mrb) << std::endl; + + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + } + + mrb_close(mrb); + return result_code; +} + diff --git a/test/reference.cc b/test/reference.cc new file mode 100644 index 0000000..fa58534 --- /dev/null +++ b/test/reference.cc @@ -0,0 +1,62 @@ + +#include +#include +#include "mrubybind.h" + +#include +using namespace std; + +class V{ +public: + int a; + V(){ + a = 0; + } +}; + +V create_v() +{ + return V(); +} + +void add_v(V& v) +{ + v.a++; +} + +int v_a(V& v) +{ + return v.a; +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb);; + b.bind_class("V"); + b.bind("create_v", create_v); + b.bind("add_v", add_v); + b.bind("v_a", v_a); + b.bind_custom_method("V", "a", v_a); + } + + int result_code = EXIT_SUCCESS; + mrb_load_string(mrb, + "puts \"start ReferenceTest\"\n" + "v = create_v\n" + "add_v v\n" + "puts \"v_a = #{v_a v}\"\n" + "add_v v\n" + "puts \"v_a = #{v.a}\"\n" + ); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + } + + mrb_close(mrb); + return result_code; +} + + diff --git a/test/string.cc b/test/string.cc new file mode 100644 index 0000000..ca66461 --- /dev/null +++ b/test/string.cc @@ -0,0 +1,33 @@ +#include +#include +#include "mrubybind.h" +#include + +#include +using namespace std; + +string emphasize(const char* str) { + return "* " + string(str) + " *"; +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("emphasize", emphasize); + } + if (mrb_gc_arena_save(mrb) != 0) { + fprintf(stderr, "Arena increased!\n"); + return EXIT_FAILURE; + } + + mrb_load_string(mrb, "puts emphasize('Hello, mruby!')"); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + return EXIT_FAILURE; + } + + mrb_close(mrb); + return EXIT_SUCCESS; +} diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 0000000..b12e1b6 --- /dev/null +++ b/test/test.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +################################################################ +# Test framework. + +function error_exit() { + echo -n -e "\033[1;31m[ERROR]\033[0;39m " + echo "$1" + exit 1 +} + +function run() { + echo -n "Testing $1 ... " + result=$(./$1) + code=$? + if [ $code -ne 0 ]; then + error_exit "exit status is not 0 [$code]" + fi + if [ "$result" != "$2" ]; then + error_exit "$2 expected, but got '$result'" + fi + echo ok +} + +function fail() { + echo -n "Testing $1 ... " + result=$(./$1) + code=$? + if [ $code -eq 0 ]; then + error_exit "Failure expected, but succeeded!" + fi + if [ "$result" != "$2" ]; then + error_exit "$2 expected, but got '$result'" + fi + echo ok +} + +################################################################ +# Test cases. + +run void 'dummy called' +run int '1234321' +run float '408' +run string '* Hello, mruby! *' +run cptr 'cptr test' +run class 'Foo::ctor(123) +690 +99980001 +Foo::dtor()' +run module 'modfunc called: 1234 +Mod::ModClass::CNST 12345 +c.get_a 4 +Mod::Mod2::ModClass::CNST 12345 +c.get_a 4' +run class_value 'start ClassPointerTest +ClassValue construct. +cv -> 7 +cv -> 8 +cv -> 7 +cv.call_block -> test7 +wk->7 +GC +ClassValue destruct. +wk->0' +run many_bind 'arena_index = 2 +start ClassPointerTest +ClassValue construct. +cv -> 7 +cv -> 8 +cv -> 7 +cv.call_block -> test7 +wk->7 +GC +ClassValue destruct. +wk->0' +run mruby_ref 'mruby_ref = 3test +mruby_ref = 3 +mruby_ref = 3toast +:a == :a = 1 +arena_index = 0' +run reference 'start ReferenceTest +v_a = 1 +v_a = 2' +run avoid_gc 'start avoid_gc +called! +start avoid_gc 2 +called! +block called!' + + +# Failure cases +fail wrong_type "TypeError: can't convert String into Fixnum, argument 1(1111)" +fail wrong_arg_num "ArgumentError: 'square': wrong number of arguments (2 for 1)" + +################################################################ +# All tests succeeded. + +echo -n -e "\033[1;32mTEST ALL SUCCEEDED!\033[0;39m\n" diff --git a/test/void.cc b/test/void.cc new file mode 100644 index 0000000..35f4f2e --- /dev/null +++ b/test/void.cc @@ -0,0 +1,30 @@ +#include +#include +#include "mrubybind.h" +#include + +void dummy() { + printf("dummy called\n"); +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("dummy", dummy); + } + if (mrb_gc_arena_save(mrb) != 0) { + fprintf(stderr, "Arena increased!\n"); + return EXIT_FAILURE; + } + + mrb_load_string(mrb, "dummy()"); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + return EXIT_FAILURE; + } + + mrb_close(mrb); + return EXIT_SUCCESS; +} diff --git a/test/wrong_arg_num.cc b/test/wrong_arg_num.cc new file mode 100644 index 0000000..667178b --- /dev/null +++ b/test/wrong_arg_num.cc @@ -0,0 +1,27 @@ +#include +#include +#include "mrubybind.h" +#include + +int square(int x) { + return x * x; +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("square", square); + } + + int result_code = EXIT_SUCCESS; + mrb_load_string(mrb, "puts square(111, 222)"); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + } + + mrb_close(mrb); + return result_code; +} diff --git a/test/wrong_type.cc b/test/wrong_type.cc new file mode 100644 index 0000000..a76bfec --- /dev/null +++ b/test/wrong_type.cc @@ -0,0 +1,27 @@ +#include +#include +#include "mrubybind.h" +#include + +int square(int x) { + return x * x; +} + +int main() { + mrb_state* mrb = mrb_open(); + + { + mrubybind::MrubyBind b(mrb); + b.bind("square", square); + } + + int result_code = EXIT_SUCCESS; + mrb_load_string(mrb, "puts square(\"1111\")"); + if (mrb->exc) { + mrb_p(mrb, mrb_obj_value(mrb->exc)); + result_code = EXIT_FAILURE; + } + + mrb_close(mrb); + return result_code; +}