Enable type information on release

This is needed for GDScript (and potentially other scripting languages)
to properly identify type errors and avoid mismatch between release and
debug versions.

This increases the release bynary size by about 889 KiB.
This commit is contained in:
George Marques 2022-04-01 10:24:20 -03:00
parent 8f06d8653c
commit 226103d166
No known key found for this signature in database
GPG Key ID: 046BD46A3201E43D
7 changed files with 48 additions and 80 deletions

View File

@ -554,6 +554,27 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit
}
}
static MethodInfo info_from_bind(MethodBind *p_method) {
MethodInfo minfo;
minfo.name = p_method->get_name();
minfo.id = p_method->get_method_id();
for (int i = 0; i < p_method->get_argument_count(); i++) {
minfo.arguments.push_back(p_method->get_argument_info(i));
}
minfo.return_val = p_method->get_return_info();
minfo.flags = p_method->get_hint_flags();
for (int i = 0; i < p_method->get_argument_count(); i++) {
if (p_method->has_default_argument(i)) {
minfo.default_arguments.push_back(p_method->get_default_argument(i));
}
}
return minfo;
}
void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) {
OBJTYPE_RLOCK;
@ -576,42 +597,24 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
}
for (List<StringName>::Element *E = type->method_order.front(); E; E = E->next()) {
MethodBind *method = type->method_map.get(E->get());
MethodInfo minfo;
minfo.name = E->get();
minfo.id = method->get_method_id();
if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name)) {
if (p_exclude_from_properties && type->methods_in_properties.has(E->get())) {
continue;
}
for (int i = 0; i < method->get_argument_count(); i++) {
//Variant::Type t=method->get_argument_type(i);
minfo.arguments.push_back(method->get_argument_info(i));
}
minfo.return_val = method->get_return_info();
minfo.flags = method->get_hint_flags();
for (int i = 0; i < method->get_argument_count(); i++) {
if (method->has_default_argument(i)) {
minfo.default_arguments.push_back(method->get_default_argument(i));
}
}
MethodBind *method = type->method_map.get(E->get());
MethodInfo minfo = info_from_bind(method);
p_methods->push_back(minfo);
}
#else
const StringName *K = NULL;
const StringName *K = nullptr;
while ((K = type->method_map.next(K))) {
MethodBind *m = type->method_map[*K];
MethodInfo mi;
mi.name = m->get_name();
p_methods->push_back(mi);
MethodInfo minfo = info_from_bind(m);
p_methods->push_back(minfo);
}
#endif

View File

@ -41,13 +41,13 @@
#define DEFVAL(m_defval) (m_defval)
//#define SIMPLE_METHODDEF
#ifdef DEBUG_METHODS_ENABLED
struct MethodDefinition {
StringName name;
#ifdef DEBUG_METHODS_ENABLED
Vector<StringName> args;
#endif
MethodDefinition() {}
MethodDefinition(const char *p_name) :
name(p_name) {}
@ -72,8 +72,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
#else
//#define NO_VARIADIC_MACROS
#ifdef NO_VARIADIC_MACROS
static _FORCE_INLINE_ const char *D_METHOD(const char *m_name, ...) {
@ -89,7 +87,6 @@ static _FORCE_INLINE_ const char *D_METHOD(const char *m_name, ...) {
#endif
#endif
class ClassDB {
public:
enum APIType {

View File

@ -7,14 +7,15 @@ class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
public:
$ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$;
#ifdef DEBUG_METHODS_ENABLED
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
#ifdef DEBUG_METHODS_ENABLED
virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
$ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$
$arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA;
$
return GodotTypeInfo::METADATA_NONE;
}
#endif
Variant::Type _get_argument_type(int p_argument) const {
$ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
$arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE;
@ -27,7 +28,6 @@ public:
$
return PropertyInfo();
}
#endif
virtual String get_instance_class() const {
return T::get_class_static();
}
@ -69,10 +69,8 @@ public:
MethodBind$argc$$ifret R$$ifconst C$ () {
#ifdef DEBUG_METHODS_ENABLED
_set_const($ifconst true$$ifnoconst false$);
_generate_argument_types($argc$);
#else
set_argument_count($argc$);
#endif
set_argument_count($argc$);
$ifret _set_returns(true); $
};
@ -98,14 +96,15 @@ public:
StringName type_name;
$ifret R$ $ifnoret void$ (__UnexistingClass::*method)($arg, P@$) $ifconst const$;
#ifdef DEBUG_METHODS_ENABLED
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
#ifdef DEBUG_METHODS_ENABLED
virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
$ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$
$arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA;
$
return GodotTypeInfo::METADATA_NONE;
}
#endif
Variant::Type _get_argument_type(int p_argument) const {
$ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
@ -121,7 +120,6 @@ public:
return PropertyInfo();
}
#endif
virtual String get_instance_class() const {
return type_name;
}
@ -163,10 +161,8 @@ public:
MethodBind$argc$$ifret R$$ifconst C$ () {
#ifdef DEBUG_METHODS_ENABLED
_set_const($ifconst true$$ifnoconst false$);
_generate_argument_types($argc$);
#else
set_argument_count($argc$);
#endif
_generate_argument_types($argc$);
$ifret _set_returns(true); $
@ -198,7 +194,6 @@ class FunctionBind$argc$$ifret R$$ifconst C$ : public MethodBind {
public:
$ifret R$ $ifnoret void$ (*method) ($ifconst const$ T *$ifargs , $$arg, P@$);
#ifdef DEBUG_METHODS_ENABLED
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
$ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$
@ -218,7 +213,6 @@ public:
$
return PropertyInfo();
}
#endif
virtual String get_instance_class() const {
return T::get_class_static();
}
@ -260,10 +254,8 @@ public:
FunctionBind$argc$$ifret R$$ifconst C$ () {
#ifdef DEBUG_METHODS_ENABLED
_set_const($ifconst true$$ifnoconst false$);
_generate_argument_types($argc$);
#else
set_argument_count($argc$);
#endif
_generate_argument_types($argc$);
$ifret _set_returns(true); $
};

View File

@ -34,12 +34,13 @@
#include "method_bind.h"
#ifdef DEBUG_METHODS_ENABLED
PropertyInfo MethodBind::get_argument_info(int p_argument) const {
ERR_FAIL_INDEX_V(p_argument, get_argument_count(), PropertyInfo());
PropertyInfo info = _gen_argument_type_info(p_argument);
#ifdef DEBUG_METHODS_ENABLED
info.name = p_argument < arg_names.size() ? String(arg_names[p_argument]) : String("arg" + itos(p_argument));
#endif
return info;
}
@ -47,7 +48,6 @@ PropertyInfo MethodBind::get_return_info() const {
return _gen_argument_type_info(-1);
}
#endif
void MethodBind::_set_const(bool p_const) {
_const = p_const;
}
@ -78,7 +78,6 @@ void MethodBind::set_default_arguments(const Vector<Variant> &p_defargs) {
default_argument_count = default_arguments.size();
}
#ifdef DEBUG_METHODS_ENABLED
void MethodBind::_generate_argument_types(int p_count) {
set_argument_count(p_count);
@ -92,25 +91,19 @@ void MethodBind::_generate_argument_types(int p_count) {
argument_types = argt;
}
#endif
MethodBind::MethodBind() {
static int last_id = 0;
method_id = last_id++;
hint_flags = METHOD_FLAGS_DEFAULT;
argument_count = 0;
default_argument_count = 0;
#ifdef DEBUG_METHODS_ENABLED
argument_types = nullptr;
#endif
_const = false;
_returns = false;
}
MethodBind::~MethodBind() {
#ifdef DEBUG_METHODS_ENABLED
if (argument_types) {
memdelete_arr(argument_types);
}
#endif
}

View File

@ -209,18 +209,16 @@ class MethodBind {
bool _returns;
protected:
#ifdef DEBUG_METHODS_ENABLED
Variant::Type *argument_types;
#ifdef DEBUG_METHODS_ENABLED
Vector<StringName> arg_names;
#endif
void _set_const(bool p_const);
void _set_returns(bool p_returns);
#ifdef DEBUG_METHODS_ENABLED
virtual Variant::Type _gen_argument_type(int p_arg) const = 0;
virtual PropertyInfo _gen_argument_type_info(int p_arg) const = 0;
void _generate_argument_types(int p_count);
#endif
void set_argument_count(int p_count) { argument_count = p_count; }
public:
@ -247,8 +245,6 @@ public:
}
}
#ifdef DEBUG_METHODS_ENABLED
_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
return argument_types[p_argument + 1];
@ -257,6 +253,7 @@ public:
PropertyInfo get_argument_info(int p_argument) const;
PropertyInfo get_return_info() const;
#ifdef DEBUG_METHODS_ENABLED
void set_argument_names(const Vector<StringName> &p_names); //set by class, db, can't be inferred otherwise
Vector<StringName> get_argument_names() const;
@ -295,14 +292,9 @@ public:
protected:
NativeCall call_method;
#ifdef DEBUG_METHODS_ENABLED
MethodInfo arguments;
#endif
public:
#ifdef DEBUG_METHODS_ENABLED
virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
if (p_arg < 0) {
return arguments.return_val;
@ -317,17 +309,12 @@ public:
return _gen_argument_type_info(p_arg).type;
}
#ifdef DEBUG_METHODS_ENABLED
virtual GodotTypeInfo::Metadata get_argument_meta(int) const {
return GodotTypeInfo::METADATA_NONE;
}
#else
virtual Variant::Type _gen_argument_type(int p_arg) const {
return Variant::NIL;
}
#endif
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Variant::CallError &r_error) {
T *instance = static_cast<T *>(p_object);
return (instance->*call_method)(p_args, p_arg_count, r_error);
@ -335,25 +322,29 @@ public:
void set_method_info(const MethodInfo &p_info, bool p_return_nil_is_variant) {
set_argument_count(p_info.arguments.size());
#ifdef DEBUG_METHODS_ENABLED
Variant::Type *at = memnew_arr(Variant::Type, p_info.arguments.size() + 1);
at[0] = p_info.return_val.type;
if (p_info.arguments.size()) {
#ifdef DEBUG_METHODS_ENABLED
Vector<StringName> names;
names.resize(p_info.arguments.size());
#endif
for (int i = 0; i < p_info.arguments.size(); i++) {
at[i + 1] = p_info.arguments[i].type;
#ifdef DEBUG_METHODS_ENABLED
names.write[i] = p_info.arguments[i].name;
#endif
}
#ifdef DEBUG_METHODS_ENABLED
set_argument_names(names);
#endif
}
argument_types = at;
arguments = p_info;
if (p_return_nil_is_variant) {
arguments.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
}
#endif
}
#ifdef PTRCALL_ENABLED

View File

@ -334,8 +334,6 @@ struct PtrToArg<const RefPtr &> {
#endif // PTRCALL_ENABLED
#ifdef DEBUG_METHODS_ENABLED
template <class T>
struct GetTypeInfo<Ref<T>> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
@ -356,6 +354,4 @@ struct GetTypeInfo<const Ref<T> &> {
}
};
#endif // DEBUG_METHODS_ENABLED
#endif // REFERENCE_H

View File

@ -31,8 +31,6 @@
#ifndef GET_TYPE_INFO_H
#define GET_TYPE_INFO_H
#ifdef DEBUG_METHODS_ENABLED
template <bool C, typename T = void>
struct EnableIf {
typedef T type;
@ -284,6 +282,4 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
#define MAKE_ENUM_TYPE_INFO(m_enum)
#define CLASS_INFO(m_type)
#endif // DEBUG_METHODS_ENABLED
#endif // GET_TYPE_INFO_H