include/rucy/extension.h.erb in rucy-0.1.12 vs include/rucy/extension.h.erb in rucy-0.1.13

- old
+ new

@@ -2,12 +2,10 @@ #pragma once #ifndef __RUCY_EXTENSION_H__ #define __RUCY_EXTENSION_H__ -#include <typeinfo> -#include <boost/dynamic_bitset.hpp> #include <xot/ref.h> #include <xot/string.h> #include <rucy/rucy.h> #include <rucy/value.h> #include <rucy/exception.h> @@ -21,26 +19,36 @@ } #define RUCY_DECLARE_VALUE_TO(native_class) \ namespace Rucy \ { \ - template <> native_class* value_to<native_class*> (Value value, bool); \ - template <> native_class& value_to<native_class&> (Value value, bool convert); \ - template <> native_class value_to<native_class> (Value value, bool convert); \ + template <> native_class* value_to< native_class*> (Value value, bool); \ + template <> const native_class* value_to<const native_class*> (Value value, bool); \ + template <> native_class& value_to< native_class&> (Value value, bool convert); \ + template <> const native_class& value_to<const native_class&> (Value value, bool convert); \ } +#define RUCY_DECLARE_VALUE_OR_ARRAY_TO(native_class) \ + RUCY_DECLARE_VALUE_TO(native_class) \ + namespace Rucy \ + { \ + template <> native_class value_to<native_class> (Value value, bool convert); \ + template <> native_class value_to<native_class> (int argc, const Value* argv, bool convert); \ + } + #define RUCY_DECLARE_WRAPPER_VALUE_FROM(native_class) \ namespace Rucy \ { \ Value value (native_class* obj); \ Value value (native_class* obj, Value klass); \ } #define RUCY_DECLARE_WRAPPER_VALUE_TO(native_class) \ namespace Rucy \ { \ - template <> native_class* value_to<native_class*> (Value value, bool convert); \ + template <> native_class* value_to< native_class*> (Value value, bool convert); \ + template <> const native_class* value_to<const native_class*> (Value value, bool convert); \ } #define RUCY_DEFINE_VALUE_FROM(native_class) \ namespace Rucy \ { \ @@ -62,20 +70,44 @@ template <> native_class* \ value_to<native_class*> (Value value, bool) \ { \ return get_type_ptr<native_class>(value, get_ruby_class<native_class>()); \ } \ + template <> const native_class* \ + value_to<const native_class*> (Value value, bool convert) \ + { \ + return (const native_class*) value_to<native_class*>(value, convert); \ + } \ template <> native_class& \ value_to<native_class&> (Value value, bool convert) \ { \ native_class* obj = value_to<native_class*>(value, convert); \ if (!obj) \ rucy_error(__FILE__, __LINE__, "failed to convert from/to %s.", #native_class); \ return *obj; \ } \ + template <> const native_class& \ + value_to<const native_class&> (Value value, bool convert) \ + { \ + return (const native_class&) value_to<native_class&>(value, convert); \ + } \ } +#define RUCY_DEFINE_VALUE_OR_ARRAY_TO(native_class) \ + RUCY_DEFINE_VALUE_TO(native_class) \ + namespace Rucy \ + { \ + template <> native_class \ + value_to<native_class> (Value value, bool convert) \ + { \ + if (value.is_array()) \ + return value_to<native_class>(value.size(), value.as_array(), convert); \ + else \ + return value_to<native_class>(1, &value, convert); \ + } \ + } + #define RUCY_DEFINE_WRAPPER_VALUE_FROM(native_class) \ namespace Rucy \ { \ Value \ value (native_class* obj) \ @@ -84,25 +116,30 @@ } \ Value \ value (native_class* obj, Value klass) \ { \ if (!obj) return nil(); \ - Value* pval = (Value*) obj->rucy_value(); \ - if (!pval) return new_ref(klass, obj); \ - if (pval->is_nil()) *pval = new_wrapper(klass, obj); \ - return *pval; \ + GlobalValue* wrapped = (GlobalValue*) obj->rucy_wrapper_value(); \ + if (!wrapped) return new_ref(klass, obj); \ + if (wrapped->is_nil()) *wrapped = new_wrapper(klass, obj); \ + return *wrapped; \ } \ } #define RUCY_DEFINE_WRAPPER_VALUE_TO(native_class) \ namespace Rucy \ { \ template <> native_class* \ - value_to<native_class*> (Value value, bool convert) \ + value_to<native_class*> (Value value, bool) \ { \ return get_type_ptr<native_class>(value, get_ruby_class<native_class>()); \ } \ + template <> const native_class* \ + value_to<const native_class*> (Value value, bool convert) \ + { \ + return (const native_class*) value_to<native_class*>(value, convert); \ + } \ } #define RUCY_DECLARE_VALUE_FROM_TO(native_class) \ RUCY_DECLARE_VALUE_FROM(native_class) \ RUCY_DECLARE_VALUE_TO(native_class) @@ -113,10 +150,22 @@ #define RUCY_VALUE_FROM_TO(native_class) \ RUCY_DECLARE_VALUE_FROM_TO(native_class) \ RUCY_DEFINE_VALUE_FROM_TO(native_class) +#define RUCY_DECLARE_VALUE_OR_ARRAY_FROM_TO(native_class) \ + RUCY_DECLARE_VALUE_FROM(native_class) \ + RUCY_DECLARE_VALUE_OR_ARRAY_TO(native_class) + +#define RUCY_DEFINE_VALUE_OR_ARRAY_FROM_TO(native_class) \ + RUCY_DEFINE_VALUE_FROM(native_class) \ + RUCY_DEFINE_VALUE_OR_ARRAY_TO(native_class) + +#define RUCY_VALUE_OR_ARRAY_FROM_TO(native_class) \ + RUCY_DECLARE_VALUE_OR_ARRAY_FROM_TO(native_class) \ + RUCY_DEFINE_VALUE_OR_ARRAY_FROM_TO(native_class) + #define RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(native_class) \ RUCY_DECLARE_WRAPPER_VALUE_FROM(native_class) \ RUCY_DECLARE_WRAPPER_VALUE_TO(native_class) #define RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(native_class) \ @@ -126,29 +175,12 @@ #define RUCY_WRAPPER_VALUE_FROM_TO(native_class) \ RUCY_DECLARE_WRAPPER_VALUE_FROM_TO(native_class) \ RUCY_DEFINE_WRAPPER_VALUE_FROM_TO(native_class) -#define RUCY_OVERRIDE_BEGIN(super_class) \ - typedef super_class Super; \ - enum { OVERRIDE_ID_FIRST = super_class::OVERRIDE_ID_LAST - 1, - -#define RUCY_OVERRIDE_END \ - OVERRIDE_ID_LAST }; - -#define RUCY_OVERRIDE_ID(name) \ - OID_##name, - -#define RUCY_IS_OVERRIDABLE() \ - this->is_overridable() - -#define RUCY_IS_OVERRIDDEN(name) \ - this->is_overridden(name, OID_##name) - - #define RUCY_TRY \ - RubyValue RUCY__rubyexception__ = nil(); \ + Rucy::RubyValue RUCY__rubyexception__ = Rucy::nil(); \ int RUCY__rubyjumptag__ = 0; \ \ goto RUCY__ruby_try_start__; \ \ RUCY__ruby_jump_tag__: \ @@ -205,39 +237,29 @@ RUCY__rubyexception__ = (exception); \ goto RUCY__ruby_raise_exception__ #define RUCY_DEF_ALLOC(name, klass) \ - RubyValue name (Value klass) \ + Rucy::RubyValue name (Rucy::Value klass) \ { \ RUCY_TRY #define RUCY_DEFN(name) \ - RubyValue name (int argc, const Value* argv, Value self) \ + Rucy::RubyValue name (int argc, const Rucy::Value* argv, Rucy::Value self) \ { \ RUCY_TRY % NTIMES.each do |n| #define RUCY_DEF<%= n %>(name<%= params(n) {|i| ", v#{i}"} %>) \ - RubyValue name (Value self<%= params(n) {|i| ", Value v#{i}"} %>) \ + Rucy::RubyValue name (Rucy::Value self<%= params(n) {|i| ", Rucy::Value v#{i}"} %>) \ { \ RUCY_TRY % end -#define RUCY_DEF_clear_override_flags(name, native_class) \ - RUCY_DEF0(name) \ - { \ - RUCY_CHECK_OBJ(native_class, self); \ - ClassWrapper<native_class>* obj = \ - dynamic_cast<ClassWrapper<native_class>*>(to<native_class*>(self)); \ - if (obj) obj->clear_override_flags(); \ - } \ - RUCY_END - #define RUCY_END \ RUCY_CATCH \ - return nil(); \ + return Rucy::nil(); \ } #define RUCY_CHECK_OBJ(native_class, obj) \ do \ @@ -249,16 +271,17 @@ while(0) #define RUCY_CHECK_OBJECT(native_class, obj) \ do \ { \ - native_class* p = Rucy::get_type_ptr<native_class>(obj, get_ruby_class<native_class>()); \ + native_class* p = \ + Rucy::get_type_ptr<native_class>(obj, Rucy::get_ruby_class<native_class>()); \ if (!p || !*p) Rucy::invalid_object_error(__FILE__, __LINE__); \ } \ while(0) -#define RUCY_WRAPPER_CALL(native_class, obj, fun) \ +#define RUCY_CALL_SUPER(obj, fun) \ ((obj)->rucy_disable_override() ? (obj)->fun : (obj)->fun) namespace Rucy { @@ -274,194 +297,84 @@ template <typename T> Class get_ruby_class (); - template <typename T> - class ClassWrapper : public T + template <typename RefCountableT> + class ClassWrapper : public RefCountableT { - typedef ClassWrapper This; + typedef ClassWrapper This; + typedef RefCountableT RucyWrapped; + public: - typedef T RucyWrapped; - GlobalValue value; ClassWrapper () : value(nil(), true), overridable(true) { } - virtual void retain (void* by_ruby_value = NULL) const + void retain (intptr_t by_ruby) const override { - if (!by_ruby_value) - { - refc_set_aux(refc_aux() + 1); - if (refc_aux() == 1) value.gc(false); - } - + if (!by_ruby) value.disable_gc(); RucyWrapped::retain(); } - virtual void release (void* by_ruby_value = NULL) const + void release (intptr_t by_ruby) const override { - if (!by_ruby_value && refc_aux() > 0) - { - refc_set_aux(refc_aux() - 1); - if (refc_aux() == 0) value.gc(true); - } - + if (!by_ruby) value.enable_gc(); RucyWrapped::release(); } - virtual void clear_override_flags () - { - override_flags.reset(); - } - virtual bool is_overridable () const { - if (!overridable) - { - overridable = true; + if (value.is_nil()) return false; - } - return true; - } - - virtual bool is_overridden (const Symbol& name, uint id) const - { - if (id <= OVERRIDE_ID_UNKNOWN) - return false; - if (!overridable) { overridable = true; return false; } - bool checked = false, overridden = false; - get_override_flag(&checked, &overridden, id); - if (checked) return overridden; - - overridden = check_overridden(name); - if (!set_override_flag(id, true, overridden)) - return false; - - return overridden; + return true; } - virtual void* rucy_value () const + void* rucy_wrapper_value () const override { return (void*) &value; } - virtual bool rucy_disable_override () const + bool rucy_disable_override () const override { overridable = false; return true; } - protected: - - enum - { - - OVERRIDE_ID_UNKNOWN = 0, - - OVERRIDE_ID_LAST, - - OVERRIDE_ID_MAX = 256 - - }; - - virtual ushort refc_aux () const - { - return RucyWrapped::refc_aux(); - } - - virtual void refc_set_aux (ushort aux) const - { - RucyWrapped::refc_set_aux(aux); - } - private: - mutable boost::dynamic_bitset<> override_flags; - mutable bool overridable; - bool check_overridden (const Symbol& name) const - { - RUCY_SYM(method); - RUCY_SYM(owner); - RUCY_SYM(instance_methods); - RUCY_SYM_Q(include); - RUCY_SYM(clear_override_flags); - return !value - .call(method, name.value()) - .call(owner) - .call(instance_methods, false) - .call(include, clear_override_flags.value()); - } - - void get_override_flag (bool* checked, bool* overridden, uint id) const - { - assert(checked || overridden); - - int checked_pos = id2index(id); - int overridden_pos = checked_pos + 1; - bool valid = 0 <= checked_pos && overridden_pos < (int) override_flags.size(); - if (checked) *checked = valid ? override_flags[checked_pos] : false; - if (overridden) *overridden = valid ? override_flags[overridden_pos] : false; - } - - bool set_override_flag (uint id, bool checked, bool overridden) const - { - assert(id < OVERRIDE_ID_MAX); - - int checked_pos = id2index(id); - if (checked_pos < 0) return true; - - int overridden_pos = checked_pos + 1; - if (overridden_pos >= (int) override_flags.size()) - override_flags.resize(overridden_pos + 1); - - override_flags[checked_pos] = checked; - override_flags[overridden_pos] = overridden; - return true; - } - - int id2index (uint id) const - { - return (id - 1) * 2; - } - };// ClassWrapper - template <typename T> inline void mark_type (void* p) - { - if (p) ((T*) p)->mark(); - } - template <typename T> inline void delete_type (void* p) { delete (T*) p; } template <typename T> inline void release_ref (void* p) { - if (p) ((T*) p)->release((void*) true);// 'true' means by-ruby-value. + if (p) ((T*) p)->release(); } template <typename T> inline void release_wrapper (void* p) { - if (p) ((T*) p)->Xot::template RefCountable<>::release(); + if (p) ((T*) p)->release(true); } template <typename T> inline Value new_type ( Value klass, T* ptr, @@ -483,11 +396,11 @@ template <typename T> inline Value new_ref ( Value klass, T* ptr, RUBY_DATA_FUNC mark = NULL, RUBY_DATA_FUNC free = release_ref<T>) { - if (ptr) ptr->retain((void*) true);// 'true' means by-ruby-value + if (ptr) ptr->retain(); return new_type(klass, ptr, mark, free); } template <typename T> inline Value new_ref ( Value klass, @@ -500,10 +413,10 @@ template <typename T> inline Value new_wrapper ( Value klass, T* ptr, RUBY_DATA_FUNC mark = NULL, RUBY_DATA_FUNC free = release_wrapper<T>) { - if (ptr) ptr->Xot::template RefCountable<>::retain(); + if (ptr) ptr->retain(true); return new_type(klass, ptr, mark, free); } template <typename T> inline Value new_wrapper ( Value klass,