Use script instance binding for objects constructed from C#

Only possible if the object class is a "native type". If the object class is a user class (that derives a "native type") then a script is needed.
Since CSharpLanguage does cleanup of script instance bindings when finished, cases like #25621 will no longer cause problems.

Fixed ~Object() trying to free script instance bindings after the language has already been removed, which would result in a NULL dereference.
This commit is contained in:
Ignacio Etcheverry 2019-02-04 20:39:02 +01:00
parent 16d402147b
commit 9df44c2d2c
9 changed files with 88 additions and 19 deletions

View file

@ -1113,19 +1113,23 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
SCOPED_MUTEX_LOCK(language_bind_mutex);
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
if (match)
return (void *)match;
CSharpScriptBinding script_binding;
if (!setup_csharp_script_binding(script_binding, p_object))
return NULL;
void *data;
return (void *)insert_script_binding(p_object, script_binding);
}
{
SCOPED_MUTEX_LOCK(language_bind_mutex);
data = (void *)script_bindings.insert(p_object, script_binding);
}
Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding) {
return data;
return script_bindings.insert(p_object, p_script_binding);
}
void CSharpLanguage::free_instance_binding_data(void *p_data) {
@ -2279,17 +2283,18 @@ void CSharpScript::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &CSharpScript::_new, MethodInfo(Variant::OBJECT, "new"));
}
Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class) {
Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native) {
// This method should not fail
CRASH_COND(!p_class);
// TODO: 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 = GDMonoUtils::get_class_native_base(script->script_class);
script->native = p_native;
CRASH_COND(script->native == NULL);