Просмотр исходного кода

Merge pull request #58244 from V-Sekai/typed_fail_case_return

Rémi Verschelde 3 лет назад
Родитель
Сommit
e3b70f3582
2 измененных файлов с 37 добавлено и 4 удалено
  1. 2 0
      modules/gdscript/gdscript_function.h
  2. 35 4
      modules/gdscript/gdscript_vm.cpp

+ 2 - 0
modules/gdscript/gdscript_function.h

@@ -502,6 +502,8 @@ private:
 
 	List<StackDebug> stack_debug;
 
+	Variant _get_default_variant_for_data_type(const GDScriptDataType &p_data_type);
+
 	_FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, Variant *p_stack, String &r_error) const;
 	_FORCE_INLINE_ String _get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const;
 

+ 35 - 4
modules/gdscript/gdscript_vm.cpp

@@ -123,6 +123,34 @@ static String _get_var_type(const Variant *p_var) {
 }
 #endif // DEBUG_ENABLED
 
+Variant GDScriptFunction::_get_default_variant_for_data_type(const GDScriptDataType &p_data_type) {
+	if (p_data_type.kind == GDScriptDataType::BUILTIN) {
+		if (p_data_type.builtin_type == Variant::ARRAY) {
+			Array array;
+			// Typed array.
+			if (p_data_type.has_container_element_type()) {
+				const GDScriptDataType &element_type = p_data_type.get_container_element_type();
+				array.set_typed(
+						element_type.kind == GDScriptDataType::BUILTIN ? element_type.builtin_type : Variant::OBJECT,
+						element_type.native_type,
+						element_type.script_type);
+			}
+
+			return array;
+		} else {
+			Callable::CallError ce;
+			Variant variant;
+			Variant::construct(p_data_type.builtin_type, variant, nullptr, 0, ce);
+
+			ERR_FAIL_COND_V(ce.error != Callable::CallError::CALL_OK, Variant());
+
+			return variant;
+		}
+	}
+
+	return Variant();
+}
+
 String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const {
 	String err_text;
 
@@ -428,7 +456,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 	OPCODES_TABLE;
 
 	if (!_code_ptr) {
-		return Variant();
+		return _get_default_variant_for_data_type(return_type);
 	}
 
 	r_err.error = Callable::CallError::CALL_OK;
@@ -467,11 +495,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 				r_err.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
 				r_err.argument = _argument_count;
 
-				return Variant();
+				return _get_default_variant_for_data_type(return_type);
 			} else if (p_argcount < _argument_count - _default_arg_count) {
 				r_err.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 				r_err.argument = _argument_count - _default_arg_count;
-				return Variant();
+				return _get_default_variant_for_data_type(return_type);
 			} else {
 				defarg = _argument_count - p_argcount;
 			}
@@ -498,7 +526,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 				r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_err.argument = i;
 				r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
-				return Variant();
+				return _get_default_variant_for_data_type(return_type);
 			}
 			if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
 				Variant arg;
@@ -3324,6 +3352,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
 		}
 
 #endif
+		// Get a default return type in case of failure
+		retvalue = _get_default_variant_for_data_type(return_type);
+
 		OPCODE_OUT;
 	}