Repository: godotengine/godot
File: modules/gdscript/gdscript_vm.cpp (C++)

Code before:
#endif
				Callable::CallError err;
				if (call_ret) {
					GET_INSTRUCTION_ARG(ret, argc + 1);
#ifdef DEBUG_ENABLED
					Variant::Type base_type = base->get_type();
					Object *base_obj = base->get_validated_object();
					StringName base_class = base_obj ? base_obj->get_class_name() : StringName();
#endif
					base->callp(*methodname, (const Variant **)argptrs, argc, *ret, err);
#ifdef DEBUG_ENABLED
					if (ret->get_type() == Variant::NIL) {
						if (base_type == Variant::OBJECT) {
							if (base_obj) {
								MethodBind *method = ClassDB::get_method(base_class, *methodname);
								if (*methodname == CoreStringNames::get_singleton()->_free || (method && !method->has_return())) {
									err_text = R"(Trying to get a return value of a method that returns "void")";
									OPCODE_BREAK;
								}
							}
						} else if (Variant::has_builtin_method(base_type, *methodname) && !Variant::has_builtin_method_return_value(base_type, *methodname)) {
							err_text = R"(Trying to get a return value of a method that returns "void")";
							OPCODE_BREAK;
						}
					}

					if (!call_async && ret->get_type() == Variant::OBJECT) {
						// Check if getting a function state without await.
						bool was_freed = false;
						Object *obj = ret->get_validated_object_with_check(was_freed);

						if (obj && obj->is_class_ptr(GDScriptFunctionState::get_class_ptr_static())) {
							err_text = R"(Trying to call an async function without "await".)";
							OPCODE_BREAK;
						}
					}
#endif
				} else {
					Variant ret;
					base->callp(*methodname, (const Variant **)argptrs, argc, ret, err);
				}
#ifdef DEBUG_ENABLED
				if (GDScriptLanguage::get_singleton()->profiling) {
					function_call_time += OS::get_singleton()->get_ticks_usec() - call_time;
				}

				if (err.error != Callable::CallError::CALL_OK) {
					String methodstr = *methodname;
					String basestr = _get_var_type(base);
					bool is_callable = false;


Review comment (suggestion):
This is true for now, but it may change in the future with further optimizations. I wonder if there's a way to guarantee this is done properly.

In any case, I don't think the comment is relevant, since it's not clear why this is important here. The "As far as I can tell" message also don't inspire confidence. If a comment is added in the code it should be verified to be correct.

Code after:
				CHECK_SPACE(3 + instr_arg_count);

				ip += instr_arg_count;

				int argc = _code_ptr[ip + 1];
				GD_ERR_BREAK(argc < 0);

				int methodname_idx = _code_ptr[ip + 2];
				GD_ERR_BREAK(methodname_idx < 0 || methodname_idx >= _global_names_count);
				const StringName *methodname = &_global_names_ptr[methodname_idx];

				GET_INSTRUCTION_ARG(base, argc);
				Variant **argptrs = instruction_args;

#ifdef DEBUG_ENABLED
				uint64_t call_time = 0;

				if (GDScriptLanguage::get_singleton()->profiling) {
					call_time = OS::get_singleton()->get_ticks_usec();
				}
				Variant::Type base_type = base->get_type();
				Object *base_obj = base->get_validated_object();
				StringName base_class = base_obj ? base_obj->get_class_name() : StringName();
#endif

				Callable::CallError err;
				if (call_ret) {
					GET_INSTRUCTION_ARG(ret, argc + 1);
					base->callp(*methodname, (const Variant **)argptrs, argc, *ret, err);
#ifdef DEBUG_ENABLED
					if (ret->get_type() == Variant::NIL) {
						if (base_type == Variant::OBJECT) {
							if (base_obj) {
								MethodBind *method = ClassDB::get_method(base_class, *methodname);
								if (*methodname == CoreStringNames::get_singleton()->_free || (method && !method->has_return())) {
									err_text = R"(Trying to get a return value of a method that returns "void")";
									OPCODE_BREAK;
								}
							}
						} else if (Variant::has_builtin_method(base_type, *methodname) && !Variant::has_builtin_method_return_value(base_type, *methodname)) {
							err_text = R"(Trying to get a return value of a method that returns "void")";
							OPCODE_BREAK;
						}
					}

					if (!call_async && ret->get_type() == Variant::OBJECT) {
						// Check if getting a function state without await.
						bool was_freed = false;
						Object *obj = ret->get_validated_object_with_check(was_freed);

						if (obj && obj->is_class_ptr(GDScriptFunctionState::get_class_ptr_static())) {