Merge pull request #26423 from neikeq/issue-24490
Mono: Fail on script instance creation if constructor was not found
This commit is contained in:
commit
ba9bfb8593
1 changed files with 30 additions and 3 deletions
|
@ -1528,6 +1528,15 @@ MonoObject *CSharpInstance::_internal_new_managed() {
|
|||
CRASH_COND(!gchandle.is_valid());
|
||||
#endif
|
||||
|
||||
// Search the constructor first, to fail with an error if it's not found before allocating anything else.
|
||||
GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
|
||||
if (ctor == NULL) {
|
||||
ERR_PRINTS("Cannot create script instance because the class does not define a default constructor: " + script->get_path());
|
||||
|
||||
ERR_EXPLAIN("Constructor not found");
|
||||
ERR_FAIL_V(NULL);
|
||||
}
|
||||
|
||||
CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
|
||||
|
||||
ERR_FAIL_NULL_V(owner, NULL);
|
||||
|
@ -1557,7 +1566,6 @@ MonoObject *CSharpInstance::_internal_new_managed() {
|
|||
CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, owner);
|
||||
|
||||
// Construct
|
||||
GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
|
||||
ctor->invoke_raw(mono_object, NULL);
|
||||
|
||||
return mono_object;
|
||||
|
@ -1900,13 +1908,21 @@ bool CSharpScript::_update_exports() {
|
|||
MonoObject *tmp_object = mono_object_new(SCRIPTS_DOMAIN, script_class->get_mono_ptr());
|
||||
|
||||
if (!tmp_object) {
|
||||
ERR_PRINT("Failed to create temporary MonoObject");
|
||||
ERR_PRINT("Failed to allocate temporary MonoObject");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t tmp_pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed)
|
||||
|
||||
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
|
||||
|
||||
if (ctor == NULL) {
|
||||
ERR_PRINTS("Cannot construct temporary MonoObject because the class does not define a default constructor: " + get_path());
|
||||
|
||||
ERR_EXPLAIN("Constructor not found");
|
||||
ERR_FAIL_V(NULL);
|
||||
}
|
||||
|
||||
MonoException *ctor_exc = NULL;
|
||||
ctor->invoke(tmp_object, NULL, &ctor_exc);
|
||||
|
||||
|
@ -2387,6 +2403,18 @@ StringName CSharpScript::get_instance_base_type() const {
|
|||
CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) {
|
||||
|
||||
/* STEP 1, CREATE */
|
||||
|
||||
// Search the constructor first, to fail with an error if it's not found before allocating anything else.
|
||||
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount);
|
||||
if (ctor == NULL) {
|
||||
if (p_argcount == 0) {
|
||||
ERR_PRINTS("Cannot create script instance because the class does not define a default constructor: " + get_path());
|
||||
}
|
||||
|
||||
ERR_EXPLAIN("Constructor not found");
|
||||
ERR_FAIL_V(NULL);
|
||||
}
|
||||
|
||||
Ref<Reference> ref;
|
||||
if (p_isref) {
|
||||
// Hold it alive. Important if we have to dispose a script instance binding before creating the CSharpInstance.
|
||||
|
@ -2453,7 +2481,6 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
|
|||
CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, instance->owner);
|
||||
|
||||
// Construct
|
||||
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount);
|
||||
ctor->invoke(mono_object, p_args);
|
||||
|
||||
/* STEP 3, PARTY */
|
||||
|
|
Loading…
Reference in a new issue