#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 RUBY_DEF_ALLOC(base_alloc, klass) { return value(new RubyBase, klass); } RUBY_END static RUBY_DEF0(name) { CHECK(Base); return value(THIS(Base)->name()); } RUBY_END static RUBY_DEF0(call_name) { CHECK(Base); return value(THIS(Base)->name()); } RUBY_END static RUBY_DEF0(base_name_overridable) { CHECK(Base); return value(CALL(Base, THIS(Base), name_overridable())); } RUBY_END static RUBY_DEF0(call_name_overridable) { CHECK(Base); return value(THIS(Base)->name_overridable()); } RUBY_END static RUBY_DEF0(base_name_overridable_faster) { CHECK(Base); return value(CALL(Base, THIS(Base), name_overridable_faster())); } RUBY_END static RUBY_DEF0(call_name_overridable_faster) { CHECK(Base); return value(THIS(Base)->name_overridable_faster()); } RUBY_END template static RUBY_DEF0(is_name_overridable_faster_overridden) { 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()); } RUBY_END template static RUBY_DEF0(clear_override_flags) { RUCY_CHECK_OBJ(self, T, get_class()); ClassWrapper* obj = dynamic_cast*>(THIS(T)); if (obj) obj->clear_override_flags(); } RUBY_END template static RUBY_DEF1(method_added_or_removed, 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()); } RUBY_END static RUBY_DEF0(base_new_raw) { return value(new Base); } RUBY_END /* alloc function. */ static RUBY_DEF_ALLOC(sub_alloc, klass) { return value(new RubyBase, klass); } RUBY_END static RUBY_DEF0(sub_name_overridable) { CHECK(Sub); return value(CALL(Sub, THIS(Sub), name_overridable())); } RUBY_END static RUBY_DEF0(sub_name_overridable_faster) { CHECK(Sub); return value(CALL(Sub, THIS(Sub), name_overridable_faster())); } RUBY_END static RUBY_DEF0(sub_new_raw) { return value(new Sub); } RUBY_END /* alloc function. */ static RUBY_DEF_ALLOC(rubyobj_alloc, klass) { return value(new ClassWrapper, klass); } RUBY_END static Xot::Ref rubyobj_ref; static RUBY_DEF1(rubyobj_set_ref, obj) { rubyobj_ref = to(obj); return obj; } RUBY_END static RUBY_DEF0(rubyobj_clear_ref) { rubyobj_ref.reset(); } RUBY_END void Init_class () { Module mRucy = define_module("Rucy"); Module mTester = mRucy.define_module("Tester"); cBase = mTester.define_class("Base"); cBase.define_alloc_func(base_alloc); cBase.define_method( "name", name); cBase.define_method( "name_overridable", base_name_overridable); cBase.define_method( "name_overridable_faster", base_name_overridable_faster); cBase.define_method("call_name", call_name); cBase.define_method("call_name_overridable", call_name_overridable); cBase.define_method("call_name_overridable_faster", call_name_overridable_faster); 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); cBase.define_singleton_method("new_raw", base_new_raw); cSub = mTester.define_class("Sub", cBase); cSub.define_alloc_func(sub_alloc); cSub.define_method("name_overridable", sub_name_overridable); cSub.define_method("name_overridable_faster", sub_name_overridable_faster); cSub.define_method( "is_name_overridable_faster_overridden", is_name_overridable_faster_overridden); cSub.define_method("clear_override_flags", clear_override_flags); cSub.define_singleton_method("new_raw", sub_new_raw); cRubyObj = mTester.define_class("RubyObj"); cRubyObj.define_alloc_func(rubyobj_alloc); cRubyObj.define_function("set_ref", rubyobj_set_ref); cRubyObj.define_function("clear_ref", rubyobj_clear_ref); }