diff --git a/rice/cpp_api/Class.ipp b/rice/cpp_api/Class.ipp index 8ce0cb35..1cd4da97 100644 --- a/rice/cpp_api/Class.ipp +++ b/rice/cpp_api/Class.ipp @@ -24,7 +24,6 @@ namespace Rice return std::string(buffer); } - inline Class define_class_under(Object module, char const* name, const Class& superclass) { VALUE klass = detail::protect(rb_define_class_under, module.value(), name, superclass.value()); @@ -47,7 +46,15 @@ namespace Rice inline Class anonymous_class() { - return detail::protect(rb_class_new, rb_cObject); + VALUE klass = detail::protect(rb_class_new, rb_cObject); + VALUE singleton = detail::protect(rb_singleton_class, klass); + + // Ruby will reuse addresses previously assigned to other modules + // that have subsequently been garbage collected + detail::Registries::instance.natives.reset(klass); + detail::Registries::instance.natives.reset(singleton); + + return klass; } } diff --git a/rice/cpp_api/Module.ipp b/rice/cpp_api/Module.ipp index 69f09e71..7a60e7b8 100644 --- a/rice/cpp_api/Module.ipp +++ b/rice/cpp_api/Module.ipp @@ -63,7 +63,15 @@ namespace Rice inline Module anonymous_module() { - return detail::protect(rb_module_new); + VALUE klass = detail::protect(rb_module_new); + VALUE singleton = detail::protect(rb_singleton_class, klass); + + // Ruby will reuse addresses previously assigned to other modules + // that have subsequently been garbage collected + detail::Registries::instance.natives.reset(klass); + detail::Registries::instance.natives.reset(singleton); + + return klass; } } diff --git a/test/test_Address_Registration_Guard.cpp b/test/test_Address_Registration_Guard.cpp index 5988bb21..8c026f62 100644 --- a/test/test_Address_Registration_Guard.cpp +++ b/test/test_Address_Registration_Guard.cpp @@ -11,6 +11,11 @@ SETUP(Address_Registration_Guard) embed_ruby(); } +TEARDOWN(Address_Registration_Guard) +{ + rb_gc_start(); +} + TESTCASE(register_address) { VALUE v = Qnil; diff --git a/test/test_Array.cpp b/test/test_Array.cpp index 982eb25f..9864843f 100644 --- a/test/test_Array.cpp +++ b/test/test_Array.cpp @@ -24,6 +24,11 @@ SETUP(Array) embed_ruby(); } +TEARDOWN(Array) +{ + rb_gc_start(); +} + TESTCASE(default_construct) { Array a; diff --git a/test/test_Attribute.cpp b/test/test_Attribute.cpp index f879f6c0..fb75c91a 100644 --- a/test/test_Attribute.cpp +++ b/test/test_Attribute.cpp @@ -17,6 +17,7 @@ SETUP(Attribute) TEARDOWN(Attribute) { Rice::detail::Registries::instance.types.clearUnverifiedTypes(); + rb_gc_start(); } namespace diff --git a/test/test_Builtin_Object.cpp b/test/test_Builtin_Object.cpp index 03ddba55..2d5e30b3 100644 --- a/test/test_Builtin_Object.cpp +++ b/test/test_Builtin_Object.cpp @@ -11,6 +11,11 @@ SETUP(Builtin_Object) embed_ruby(); } +TEARDOWN(Builtin_Object) +{ + rb_gc_start(); +} + TESTCASE(construct_with_object) { Class c(rb_cObject); diff --git a/test/test_Class.cpp b/test/test_Class.cpp index 13834bd1..bab53362 100644 --- a/test/test_Class.cpp +++ b/test/test_Class.cpp @@ -11,6 +11,11 @@ SETUP(Class) embed_ruby(); } +TEARDOWN(Class) +{ + rb_gc_start(); +} + TESTCASE(construct) { Class c(rb_cObject); diff --git a/test/test_Constructor.cpp b/test/test_Constructor.cpp index 13c15bfc..a5bd1cb0 100644 --- a/test/test_Constructor.cpp +++ b/test/test_Constructor.cpp @@ -12,6 +12,11 @@ SETUP(Construtor) embed_ruby(); } +TEARDOWN(Constructor) +{ + rb_gc_start(); +} + namespace { class Default_Constructible diff --git a/test/test_Data_Object.cpp b/test/test_Data_Object.cpp index e6a2a157..09d3a488 100644 --- a/test/test_Data_Object.cpp +++ b/test/test_Data_Object.cpp @@ -48,7 +48,7 @@ SETUP(Data_Object) if (!Data_Type::is_bound()) { Class object(rb_cObject); - if(object.const_defined("MyDataType")) + if (object.const_defined("MyDataType")) { object.remove_const("MyDataType"); } @@ -58,6 +58,11 @@ SETUP(Data_Object) } } +TEARDOWN(Data_Object) +{ + rb_gc_start(); +} + TESTCASE(construct_from_pointer) { MyDataType* myDataType = new MyDataType; diff --git a/test/test_Data_Type.cpp b/test/test_Data_Type.cpp index d06ae8fb..4f818ab0 100644 --- a/test/test_Data_Type.cpp +++ b/test/test_Data_Type.cpp @@ -17,6 +17,7 @@ SETUP(Data_Type) TEARDOWN(Data_Type) { Rice::detail::Registries::instance.types.clearUnverifiedTypes(); + rb_gc_start(); } namespace diff --git a/test/test_Director.cpp b/test/test_Director.cpp index 8bbc1c21..a945bca5 100644 --- a/test/test_Director.cpp +++ b/test/test_Director.cpp @@ -8,6 +8,16 @@ using namespace Rice; TESTSUITE(Director); +SETUP(Director) +{ + embed_ruby(); +} + +TEARDOWN(Director) +{ + rb_gc_start(); +} + namespace { /** * Abstract base class @@ -93,11 +103,6 @@ namespace { }; }; -SETUP(Director) -{ - embed_ruby(); -} - TESTCASE(exposes_worker_as_instantiatable_class) { define_class("Worker") diff --git a/test/test_Enum.cpp b/test/test_Enum.cpp index 7d70fa25..3b806045 100644 --- a/test/test_Enum.cpp +++ b/test/test_Enum.cpp @@ -17,6 +17,7 @@ SETUP(Enum) TEARDOWN(Enum) { Rice::detail::Registries::instance.types.clearUnverifiedTypes(); + rb_gc_start(); } diff --git a/test/test_Exception.cpp b/test/test_Exception.cpp index 6129bf5c..25e4c345 100644 --- a/test/test_Exception.cpp +++ b/test/test_Exception.cpp @@ -11,6 +11,11 @@ SETUP(Exception) embed_ruby(); } +TEARDOWN(Exception) +{ + rb_gc_start(); +} + TESTCASE(construct_from_exception_object) { VALUE v = detail::protect(rb_exc_new2, rb_eRuntimeError, "foo"); diff --git a/test/test_Hash.cpp b/test/test_Hash.cpp index fdb1f0e0..e624d62a 100644 --- a/test/test_Hash.cpp +++ b/test/test_Hash.cpp @@ -15,6 +15,11 @@ SETUP(Hash) embed_ruby(); } +TEARDOWN(Hash) +{ + rb_gc_start(); +} + TESTCASE(default_construct) { Hash h; diff --git a/test/test_Inheritance.cpp b/test/test_Inheritance.cpp index ba841fe3..9082b0ae 100644 --- a/test/test_Inheritance.cpp +++ b/test/test_Inheritance.cpp @@ -80,6 +80,11 @@ SETUP(Inheritance) Data_Type::unbind(); } +TEARDOWN(Inheritance) +{ + rb_gc_start(); +} + TESTCASE(return_base_pointer) { Class rcNotification = define_class("Notification"); diff --git a/test/test_Iterator.cpp b/test/test_Iterator.cpp index 88f36dd3..3f4c9a31 100644 --- a/test/test_Iterator.cpp +++ b/test/test_Iterator.cpp @@ -11,6 +11,11 @@ SETUP(Iterator) embed_ruby(); } +TEARDOWN(Iterator) +{ + rb_gc_start(); +} + namespace { class Container diff --git a/test/test_Jump_Tag.cpp b/test/test_Jump_Tag.cpp index 3be1afe0..03239323 100644 --- a/test/test_Jump_Tag.cpp +++ b/test/test_Jump_Tag.cpp @@ -9,6 +9,11 @@ SETUP(Jump_Tag) { } +TEARDOWN(Jump_Tag) +{ + rb_gc_start(); +} + TESTCASE(construct) { Jump_Tag jump_tag(42); diff --git a/test/test_Keep_Alive.cpp b/test/test_Keep_Alive.cpp index 969ba104..de696afa 100644 --- a/test/test_Keep_Alive.cpp +++ b/test/test_Keep_Alive.cpp @@ -60,6 +60,11 @@ SETUP(Keep_Alive) embed_ruby(); } +TEARDOWN(Keep_Alive) +{ + rb_gc_start(); +} + TESTCASE(test_arg) { define_class("Listener") diff --git a/test/test_Keep_Alive_No_Wrapper.cpp b/test/test_Keep_Alive_No_Wrapper.cpp index ac0114eb..9218feee 100644 --- a/test/test_Keep_Alive_No_Wrapper.cpp +++ b/test/test_Keep_Alive_No_Wrapper.cpp @@ -56,6 +56,11 @@ SETUP(Keep_Alive_No_Wrapper) embed_ruby(); } +TEARDOWN(Keep_Alive_No_Wrapper) +{ + rb_gc_start(); +} + TESTCASE(test_keep_alive_no_wrapper) { define_class("Animal") diff --git a/test/test_Memory_Management.cpp b/test/test_Memory_Management.cpp index ada64c3a..b832d41d 100644 --- a/test/test_Memory_Management.cpp +++ b/test/test_Memory_Management.cpp @@ -11,6 +11,11 @@ SETUP(Memory_Management) embed_ruby(); } +TEARDOWN(Memory_Management) +{ + rb_gc_start(); +} + namespace { class TestClass { diff --git a/test/test_Module.cpp b/test/test_Module.cpp index c2ecd7b9..6ca7d7ec 100644 --- a/test/test_Module.cpp +++ b/test/test_Module.cpp @@ -13,6 +13,11 @@ SETUP(Module) embed_ruby(); } +TEARDOWN(Module) +{ + rb_gc_start(); +} + TESTCASE(FromConstant) { Module m(rb_mEnumerable); diff --git a/test/test_Native_Registry.cpp b/test/test_Native_Registry.cpp index a4c892a0..ce9a94a9 100644 --- a/test/test_Native_Registry.cpp +++ b/test/test_Native_Registry.cpp @@ -13,6 +13,11 @@ SETUP(NativeRegistry) embed_ruby(); } +TEARDOWN(NativeRegistry) +{ + rb_gc_start(); +} + TESTCASE(collisions) { std::array classes; diff --git a/test/test_Object.cpp b/test/test_Object.cpp index 74f3516e..2a90be1e 100644 --- a/test/test_Object.cpp +++ b/test/test_Object.cpp @@ -11,6 +11,11 @@ SETUP(Object) embed_ruby(); } +TEARDOWN(Object) +{ + rb_gc_start(); +} + TESTCASE(default_construct) { Object o; diff --git a/test/test_Overloads.cpp b/test/test_Overloads.cpp index 9f8c9393..d14d1bd0 100644 --- a/test/test_Overloads.cpp +++ b/test/test_Overloads.cpp @@ -12,6 +12,11 @@ SETUP(Overloads) embed_ruby(); } +TEARDOWN(Overloads) +{ + rb_gc_start(); +} + namespace { std::string run() diff --git a/test/test_Ownership.cpp b/test/test_Ownership.cpp index 31312319..57ed7a6f 100644 --- a/test/test_Ownership.cpp +++ b/test/test_Ownership.cpp @@ -131,6 +131,11 @@ SETUP(Ownership) define_method("keep_reference", &Factory::keepReference); } +TEARDOWN(Ownership) +{ + rb_gc_start(); +} + TESTCASE(TransferPointer) { Factory::reset(); diff --git a/test/test_Self.cpp b/test/test_Self.cpp index 911c860b..49d102c2 100644 --- a/test/test_Self.cpp +++ b/test/test_Self.cpp @@ -89,6 +89,11 @@ SETUP(Self) }); } +TEARDOWN(Self) +{ + rb_gc_start(); +} + TESTCASE(SelfPointer) { SelfClass::reset(); diff --git a/test/test_Stl_Map.cpp b/test/test_Stl_Map.cpp index b72634ba..568dd20d 100644 --- a/test/test_Stl_Map.cpp +++ b/test/test_Stl_Map.cpp @@ -15,6 +15,11 @@ SETUP(Map) embed_ruby(); } +TEARDOWN(Map) +{ + rb_gc_start(); +} + namespace { diff --git a/test/test_Stl_Optional.cpp b/test/test_Stl_Optional.cpp index 93e8d3db..29f90e1e 100644 --- a/test/test_Stl_Optional.cpp +++ b/test/test_Stl_Optional.cpp @@ -50,6 +50,11 @@ SETUP(Optional) makeOptionalClass(); } +TEARDOWN(Optional) +{ + rb_gc_start(); +} + TESTCASE(OptionalReturn) { Module m = define_module("Testing"); diff --git a/test/test_Stl_Pair.cpp b/test/test_Stl_Pair.cpp index e89b0835..ef32b94c 100644 --- a/test/test_Stl_Pair.cpp +++ b/test/test_Stl_Pair.cpp @@ -14,6 +14,11 @@ SETUP(Pair) embed_ruby(); } +TEARDOWN(Pair) +{ + rb_gc_start(); +} + TESTCASE(CreatePair) { Module m = define_module("Testing"); diff --git a/test/test_Stl_Reference_Wrapper.cpp b/test/test_Stl_Reference_Wrapper.cpp index c0bcfd34..2285f19c 100644 --- a/test/test_Stl_Reference_Wrapper.cpp +++ b/test/test_Stl_Reference_Wrapper.cpp @@ -61,6 +61,11 @@ SETUP(ReferenceWrapper) makeReferenceWrapperClass(); } +TEARDOWN(ReferenceWrapper) +{ + rb_gc_start(); +} + TESTCASE(Return) { Module m = define_module("Testing"); diff --git a/test/test_Stl_String_View.cpp b/test/test_Stl_String_View.cpp index e6080f33..29be20f2 100644 --- a/test/test_Stl_String_View.cpp +++ b/test/test_Stl_String_View.cpp @@ -15,6 +15,11 @@ SETUP(StlStringView) embed_ruby(); } +TEARDOWN(StlStringView) +{ + rb_gc_start(); +} + TESTCASE(std_string_view_to_ruby) { ASSERT(rb_equal(String("").value(), detail::to_ruby(std::string_view("")))); diff --git a/test/test_Stl_Unordered_Map.cpp b/test/test_Stl_Unordered_Map.cpp index 89ea46e5..919c9caf 100644 --- a/test/test_Stl_Unordered_Map.cpp +++ b/test/test_Stl_Unordered_Map.cpp @@ -15,6 +15,11 @@ SETUP(UnorderedMap) embed_ruby(); } +TEARDOWN(UnorderedMap) +{ + rb_gc_start(); +} + namespace { diff --git a/test/test_Stl_Variant.cpp b/test/test_Stl_Variant.cpp index 0417b406..d7ff458b 100644 --- a/test/test_Stl_Variant.cpp +++ b/test/test_Stl_Variant.cpp @@ -289,6 +289,11 @@ SETUP(Variant) makeClassVariant(); } +TEARDOWN(Variant) +{ + rb_gc_start(); +} + TESTCASE(ClassReturns) { Module m = define_module("Testing"); diff --git a/test/test_Stl_Vector.cpp b/test/test_Stl_Vector.cpp index 8b76e743..1c4ab0fa 100644 --- a/test/test_Stl_Vector.cpp +++ b/test/test_Stl_Vector.cpp @@ -14,6 +14,11 @@ SETUP(Vector) embed_ruby(); } +TEARDOWN(Vector) +{ + rb_gc_start(); +} + namespace { class MyClass diff --git a/test/test_String.cpp b/test/test_String.cpp index df32ff11..18c1914c 100644 --- a/test/test_String.cpp +++ b/test/test_String.cpp @@ -11,6 +11,11 @@ SETUP(String) embed_ruby(); } +TEARDOWN(String) +{ + rb_gc_start(); +} + TESTCASE(default_construct) { String s; diff --git a/test/test_Struct.cpp b/test/test_Struct.cpp index 19017b1b..50b8c972 100644 --- a/test/test_Struct.cpp +++ b/test/test_Struct.cpp @@ -24,6 +24,11 @@ SETUP(Struct) embed_ruby(); } +TEARDOWN(Struct) +{ + rb_gc_start(); +} + TESTCASE(default_construct) { Struct s; diff --git a/test/test_Symbol.cpp b/test/test_Symbol.cpp index 1b8bbf9b..099ca373 100644 --- a/test/test_Symbol.cpp +++ b/test/test_Symbol.cpp @@ -11,6 +11,11 @@ SETUP(Symbol) embed_ruby(); } +TEARDOWN(Symbol) +{ + rb_gc_start(); +} + TESTCASE(construct_from_symbol) { VALUE v = ID2SYM(rb_intern("foo")); diff --git a/test/test_To_From_Ruby.cpp b/test/test_To_From_Ruby.cpp index 0f09bfbc..5882c6c1 100644 --- a/test/test_To_From_Ruby.cpp +++ b/test/test_To_From_Ruby.cpp @@ -14,6 +14,11 @@ SETUP(To_From_Ruby) embed_ruby(); } +TEARDOWN(To_From_Ruby) +{ + rb_gc_start(); +} + TESTCASE(object_to_ruby) { Object o(rb_str_new2("foo")); diff --git a/test/test_Tracking.cpp b/test/test_Tracking.cpp index 20aea6dd..e506a04c 100644 --- a/test/test_Tracking.cpp +++ b/test/test_Tracking.cpp @@ -87,6 +87,7 @@ SETUP(Tracking) TEARDOWN(Tracking) { detail::Registries::instance.instances.isEnabled = true; + rb_gc_start(); } TESTCASE(TransferPointer) diff --git a/test/test_global_functions.cpp b/test/test_global_functions.cpp index 88569bc2..30cb4a6e 100644 --- a/test/test_global_functions.cpp +++ b/test/test_global_functions.cpp @@ -11,6 +11,11 @@ SETUP(GlobalFunction) embed_ruby(); } +TEARDOWN(GlobalFunctions) +{ + rb_gc_start(); +} + namespace { bool no_args()