#include "class.h" #include using namespace Rucy; static Class cBase, cSub, cRubyObj; RUCY_WRAPPER_VALUE_FROM_TO(Base, cBase) RUCY_WRAPPER_VALUE_FROM_TO(Sub, cSub) RUCY_WRAPPER_VALUE_FROM_TO(RubyObj, cRubyObj) template Class get_class (); template <> Class get_class () {return cBase;} template <> Class get_class () {return cSub;} template class RubyBase : public ClassWrapper { typedef ClassWrapper Super; RUCY_OVERRIDE_ID_START(name_overridable_faster) RUCY_OVERRIDE_ID_LAST public: virtual const char* name_overridable () const { RUCY_OVERRIDABLE_METHOD(name_overridable, get_class(), .c_str()); } virtual const char* name_overridable_faster () const { RUCY_OVERRIDABLE_METHOD_FAST(name_overridable_faster, get_class(), .c_str()); } bool is_name_overridable_faster_overridden () const { SYM(name_overridable_faster); return RUCY_IS_OVERRIDDEN(name_overridable_faster, get_class()); } };// RubyBase #define THIS(type) to(self) #define CHECK(type) RUCY_CHECK_OBJ(self, type, c##type) #define CALL(type, obj, fun) RUCY_WRAPPER_CALL(ClassWrapper, obj, fun) /* alloc function. */ static VALUE base_alloc(VALUE klass) { return value(new RubyBase, klass); } static VALUE name(VALUE self) { CHECK(Base); return value(THIS(Base)->name()); } static VALUE call_name(VALUE self) { CHECK(Base); return value(THIS(Base)->name()); } static VALUE base_name_overridable(VALUE self) { CHECK(Base); return value(CALL(Base, THIS(Base), name_overridable())); } static VALUE call_name_overridable(VALUE self) { CHECK(Base); return value(THIS(Base)->name_overridable()); } static VALUE base_name_overridable_faster(VALUE self) { CHECK(Base); return value(CALL(Base, THIS(Base), name_overridable_faster())); } static VALUE call_name_overridable_faster(VALUE self) { CHECK(Base); return value(THIS(Base)->name_overridable_faster()); } template static VALUE is_name_overridable_faster_overridden(VALUE self) { RUCY_CHECK_OBJ(self, T, get_class()); RubyBase* obj = dynamic_cast*>(THIS(T)); if (!obj) invalid_object_error("dynamic_cast() failed."); return value(obj->is_name_overridable_faster_overridden()); } template static VALUE clear_override_flags(VALUE self) { RUCY_CHECK_OBJ(self, T, get_class()); ClassWrapper* obj = dynamic_cast*>(THIS(T)); if (obj) obj->clear_override_flags(); } template static VALUE method_added_or_removed(VALUE self, VALUE method_name) { SYMBOL(klass, "class"); SYM(name); eval( Xot::stringf( "ObjectSpace.each_object(%s) {|o| o.clear_override_flags}", (singleton ? self(klass) : self)(name).c_str()).c_str()); } static VALUE base_new_raw(VALUE self) { return value(new Base); } /* alloc function. */ static VALUE sub_alloc(VALUE klass) { return value(new RubyBase, klass); } static VALUE sub_name_overridable(VALUE self) { CHECK(Sub); return value(CALL(Sub, THIS(Sub), name_overridable())); } static VALUE sub_name_overridable_faster(VALUE self) { CHECK(Sub); return value(CALL(Sub, THIS(Sub), name_overridable_faster())); } static VALUE sub_new_raw(VALUE self) { return value(new Sub); } /* alloc function. */ static VALUE rubyobj_alloc(VALUE klass) { return value(new ClassWrapper, klass); } static Xot::Ref rubyobj_ref; static VALUE rubyobj_set_ref(VALUE self, VALUE obj) { rubyobj_ref = to(obj); return obj; } static VALUE rubyobj_clear_ref(VALUE self) { rubyobj_ref.reset(); } void Init_class () { Module mRucy = rb_define_module("Rucy"); Module mTester = rb_define_module_under(mRucy, "Tester"); cBase = rb_define_class_under(mTester, "Base", rb_cObject); rb_define_alloc_func(cBase, base_alloc); rb_define_method(cBase, "name", RUBY_METHOD_FUNC(name), 0); rb_define_method(cBase, "name_overridable", RUBY_METHOD_FUNC(base_name_overridable), 0); rb_define_method(cBase, "name_overridable_faster", RUBY_METHOD_FUNC(base_name_overridable_faster), 0); rb_define_method(cBase, "call_name", RUBY_METHOD_FUNC(call_name), 0); rb_define_method(cBase, "call_name_overridable", RUBY_METHOD_FUNC(call_name_overridable), 0); rb_define_method(cBase, "call_name_overridable_faster", RUBY_METHOD_FUNC(call_name_overridable_faster), 0); cBase.define_method( "is_name_overridable_faster_overridden", is_name_overridable_faster_overridden); cBase.define_method("clear_override_flags", clear_override_flags); cBase.define_method("singleton_method_added", method_added_or_removed); cBase.define_method("singleton_method_removed", method_added_or_removed); cBase.define_singleton_method("method_added", method_added_or_removed); cBase.define_singleton_method("method_removed", method_added_or_removed); rb_define_singleton_method(cBase, "new_raw", RUBY_METHOD_FUNC(base_new_raw), 0); cSub = rb_define_class_under(mTester, "Sub", cBase); rb_define_alloc_func(cSub, sub_alloc); rb_define_method(cSub, "name_overridable", RUBY_METHOD_FUNC(sub_name_overridable), 0); rb_define_method(cSub, "name_overridable_faster", RUBY_METHOD_FUNC(sub_name_overridable_faster), 0); cSub.define_method( "is_name_overridable_faster_overridden", is_name_overridable_faster_overridden); cSub.define_method("clear_override_flags", clear_override_flags); rb_define_singleton_method(cSub, "new_raw", RUBY_METHOD_FUNC(sub_new_raw), 0); cRubyObj = rb_define_class_under(mTester, "RubyObj", rb_cObject); rb_define_alloc_func(cRubyObj, rubyobj_alloc); rb_define_function(cRubyObj, "set_ref", RUBY_METHOD_FUNC(rubyobj_set_ref), 1); rb_define_function(cRubyObj, "clear_ref", RUBY_METHOD_FUNC(rubyobj_clear_ref), 0); }