diff options
author | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2019-07-08 15:18:38 +0200 |
---|---|---|
committer | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2019-07-08 18:07:20 +0200 |
commit | dd22cc7527049e6fa4d1a095a8fcd4ebffeaabd4 (patch) | |
tree | de9de328869a1476098c0353db86001d4d884a43 /modules/mono | |
parent | aa3b8f7dbbf04c54795431eed40c63f9ed8e0fe1 (diff) |
C#: Fix some crashes during assemblies reloading
Diffstat (limited to 'modules/mono')
-rw-r--r-- | modules/mono/csharp_script.cpp | 74 | ||||
-rw-r--r-- | modules/mono/csharp_script.h | 1 |
2 files changed, 42 insertions, 33 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index b5c91a8585..06a5c65d3c 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -867,6 +867,11 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { script->reload(p_soft_reload); script->update_exports(); + + if (!script->valid) { + script->pending_reload_instances.clear(); + continue; + } } else { const StringName &class_namespace = script->tied_class_namespace_for_reload; const StringName &class_name = script->tied_class_name_for_reload; @@ -897,12 +902,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { GDMonoClass *native = GDMonoUtils::get_class_native_base(script_class); - Ref<CSharpScript> new_script = CSharpScript::create_for_managed_type(script_class, native); - CRASH_COND(new_script.is_null()); - - new_script->pending_reload_instances = script->pending_reload_instances; - new_script->pending_reload_state = script->pending_reload_state; - script = new_script; + CSharpScript::initialize_for_managed_type(script, script_class, native); } String native_name = NATIVE_GDMONOCLASS_NAME(script->native); @@ -953,7 +953,6 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { CRASH_COND(si != NULL); #endif // Re-create script instance - obj->set_script(script.get_ref_ptr()); // will create the script instance as well } } @@ -2673,35 +2672,46 @@ void CSharpScript::_bind_methods() { Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native) { - // This method should not fail + // This method should not fail, only assertions allowed CRASH_COND(p_class == NULL); // TODO OPTIMIZE: Cache the 'CSharpScript' associated with this 'p_class' instead of allocating a new one every time Ref<CSharpScript> script = memnew(CSharpScript); - script->name = p_class->get_name(); - script->script_class = p_class; - script->native = p_native; + initialize_for_managed_type(script, p_class, p_native); + + return script; +} + +void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native) { + + // This method should not fail, only assertions allowed + + CRASH_COND(p_class == NULL); + + p_script->name = p_class->get_name(); + p_script->script_class = p_class; + p_script->native = p_native; - CRASH_COND(script->native == NULL); + CRASH_COND(p_script->native == NULL); - GDMonoClass *base = script->script_class->get_parent_class(); + GDMonoClass *base = p_script->script_class->get_parent_class(); - if (base != script->native) - script->base = base; + if (base != p_script->native) + p_script->base = base; - script->valid = true; - script->tool = script->script_class->has_attribute(CACHED_CLASS(ToolAttribute)); + p_script->valid = true; + p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute)); - if (!script->tool) { - GDMonoClass *nesting_class = script->script_class->get_nesting_class(); - script->tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute)); + if (!p_script->tool) { + GDMonoClass *nesting_class = p_script->script_class->get_nesting_class(); + p_script->tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute)); } #if TOOLS_ENABLED - if (!script->tool) { - script->tool = script->script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly(); + if (!p_script->tool) { + p_script->tool = p_script->script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly(); } #endif @@ -2710,10 +2720,10 @@ Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GD // Native base methods must be fetched before the current class. // Not needed if the script class itself is a native class. - if (script->script_class != script->native) { - GDMonoClass *native_top = script->native; + if (p_script->script_class != p_script->native) { + GDMonoClass *native_top = p_script->native; while (native_top) { - native_top->fetch_methods_with_godot_api_checks(script->native); + native_top->fetch_methods_with_godot_api_checks(p_script->native); if (native_top == CACHED_CLASS(GodotObject)) break; @@ -2723,19 +2733,17 @@ Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GD } #endif - script->script_class->fetch_methods_with_godot_api_checks(script->native); + p_script->script_class->fetch_methods_with_godot_api_checks(p_script->native); // Need to fetch method from base classes as well - GDMonoClass *top = script->script_class; - while (top && top != script->native) { - top->fetch_methods_with_godot_api_checks(script->native); + GDMonoClass *top = p_script->script_class; + while (top && top != p_script->native) { + top->fetch_methods_with_godot_api_checks(p_script->native); top = top->get_parent_class(); } - script->load_script_signals(script->script_class, script->native); - script->_update_member_info_no_exports(); - - return script; + p_script->load_script_signals(p_script->script_class, p_script->native); + p_script->_update_member_info_no_exports(); } bool CSharpScript::can_instance() const { diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index d31a1c35d2..76c7976285 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -144,6 +144,7 @@ class CSharpScript : public Script { // Do not use unless you know what you are doing friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *); static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native); + static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native); protected: static void _bind_methods(); |