diff options
Diffstat (limited to 'modules/gdscript/gdscript_function.h')
-rw-r--r-- | modules/gdscript/gdscript_function.h | 287 |
1 files changed, 98 insertions, 189 deletions
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 5230773c13..177c68533e 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -45,10 +45,9 @@ class GDScriptInstance; class GDScript; class GDScriptDataType { -private: - GDScriptDataType *container_element_type = nullptr; - public: + Vector<GDScriptDataType> container_element_types; + enum Kind { UNINITIALIZED, BUILTIN, @@ -76,19 +75,20 @@ public: case BUILTIN: { Variant::Type var_type = p_variant.get_type(); bool valid = builtin_type == var_type; - if (valid && builtin_type == Variant::ARRAY && has_container_element_type()) { + if (valid && builtin_type == Variant::ARRAY && has_container_element_type(0)) { Array array = p_variant; if (array.is_typed()) { + GDScriptDataType array_container_type = get_container_element_type(0); Variant::Type array_builtin_type = (Variant::Type)array.get_typed_builtin(); StringName array_native_type = array.get_typed_class_name(); Ref<Script> array_script_type_ref = array.get_typed_script(); if (array_script_type_ref.is_valid()) { - valid = (container_element_type->kind == SCRIPT || container_element_type->kind == GDSCRIPT) && container_element_type->script_type == array_script_type_ref.ptr(); + valid = (array_container_type.kind == SCRIPT || array_container_type.kind == GDSCRIPT) && array_container_type.script_type == array_script_type_ref.ptr(); } else if (array_native_type != StringName()) { - valid = container_element_type->kind == NATIVE && container_element_type->native_type == array_native_type; + valid = array_container_type.kind == NATIVE && array_container_type.native_type == array_native_type; } else { - valid = container_element_type->kind == BUILTIN && container_element_type->builtin_type == array_builtin_type; + valid = array_container_type.kind == BUILTIN && array_container_type.builtin_type == array_builtin_type; } } else { valid = false; @@ -147,51 +147,32 @@ public: return false; } - operator PropertyInfo() const { - PropertyInfo info; - info.usage = PROPERTY_USAGE_NONE; - if (has_type) { - switch (kind) { - case UNINITIALIZED: - break; - case BUILTIN: { - info.type = builtin_type; - } break; - case NATIVE: { - info.type = Variant::OBJECT; - info.class_name = native_type; - } break; - case SCRIPT: - case GDSCRIPT: { - info.type = Variant::OBJECT; - info.class_name = script_type->get_instance_base_type(); - } break; - } - } else { - info.type = Variant::NIL; - info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + void set_container_element_type(int p_index, const GDScriptDataType &p_element_type) { + ERR_FAIL_COND(p_index < 0); + while (p_index >= container_element_types.size()) { + container_element_types.push_back(GDScriptDataType()); } - return info; + container_element_types.write[p_index] = GDScriptDataType(p_element_type); } - void set_container_element_type(const GDScriptDataType &p_element_type) { - container_element_type = memnew(GDScriptDataType(p_element_type)); + GDScriptDataType get_container_element_type(int p_index) const { + ERR_FAIL_INDEX_V(p_index, container_element_types.size(), GDScriptDataType()); + return container_element_types[p_index]; } - GDScriptDataType get_container_element_type() const { - ERR_FAIL_COND_V(container_element_type == nullptr, GDScriptDataType()); - return *container_element_type; + GDScriptDataType get_container_element_type_or_variant(int p_index) const { + if (p_index < 0 || p_index >= container_element_types.size()) { + return GDScriptDataType(); + } + return container_element_types[p_index]; } - bool has_container_element_type() const { - return container_element_type != nullptr; + bool has_container_element_type(int p_index) const { + return p_index >= 0 && p_index < container_element_types.size(); } - void unset_container_element_type() { - if (container_element_type) { - memdelete(container_element_type); - } - container_element_type = nullptr; + bool has_container_element_types() const { + return !container_element_types.is_empty(); } GDScriptDataType() = default; @@ -203,19 +184,14 @@ public: native_type = p_other.native_type; script_type = p_other.script_type; script_type_ref = p_other.script_type_ref; - unset_container_element_type(); - if (p_other.has_container_element_type()) { - set_container_element_type(p_other.get_container_element_type()); - } + container_element_types = p_other.container_element_types; } GDScriptDataType(const GDScriptDataType &p_other) { *this = p_other; } - ~GDScriptDataType() { - unset_container_element_type(); - } + ~GDScriptDataType() {} }; class GDScriptFunction { @@ -268,45 +244,8 @@ public: OPCODE_CALL_METHOD_BIND_RET, OPCODE_CALL_BUILTIN_STATIC, OPCODE_CALL_NATIVE_STATIC, - // ptrcall have one instruction per return type. - OPCODE_CALL_PTRCALL_NO_RETURN, - OPCODE_CALL_PTRCALL_BOOL, - OPCODE_CALL_PTRCALL_INT, - OPCODE_CALL_PTRCALL_FLOAT, - OPCODE_CALL_PTRCALL_STRING, - OPCODE_CALL_PTRCALL_VECTOR2, - OPCODE_CALL_PTRCALL_VECTOR2I, - OPCODE_CALL_PTRCALL_RECT2, - OPCODE_CALL_PTRCALL_RECT2I, - OPCODE_CALL_PTRCALL_VECTOR3, - OPCODE_CALL_PTRCALL_VECTOR3I, - OPCODE_CALL_PTRCALL_TRANSFORM2D, - OPCODE_CALL_PTRCALL_VECTOR4, - OPCODE_CALL_PTRCALL_VECTOR4I, - OPCODE_CALL_PTRCALL_PLANE, - OPCODE_CALL_PTRCALL_QUATERNION, - OPCODE_CALL_PTRCALL_AABB, - OPCODE_CALL_PTRCALL_BASIS, - OPCODE_CALL_PTRCALL_TRANSFORM3D, - OPCODE_CALL_PTRCALL_PROJECTION, - OPCODE_CALL_PTRCALL_COLOR, - OPCODE_CALL_PTRCALL_STRING_NAME, - OPCODE_CALL_PTRCALL_NODE_PATH, - OPCODE_CALL_PTRCALL_RID, - OPCODE_CALL_PTRCALL_OBJECT, - OPCODE_CALL_PTRCALL_CALLABLE, - OPCODE_CALL_PTRCALL_SIGNAL, - OPCODE_CALL_PTRCALL_DICTIONARY, - OPCODE_CALL_PTRCALL_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_BYTE_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_INT32_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_INT64_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_FLOAT32_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_FLOAT64_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_STRING_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_VECTOR2_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_VECTOR3_ARRAY, - OPCODE_CALL_PTRCALL_PACKED_COLOR_ARRAY, + OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN, + OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN, OPCODE_AWAIT, OPCODE_AWAIT_RESUME, OPCODE_CREATE_LAMBDA, @@ -437,59 +376,31 @@ private: friend class GDScript; friend class GDScriptCompiler; friend class GDScriptByteCodeGenerator; + friend class GDScriptLanguage; + StringName name; StringName source; + bool _static = false; + Vector<GDScriptDataType> argument_types; + GDScriptDataType return_type; + MethodInfo method_info; + Variant rpc_config; - mutable Variant nil; - mutable Variant *_constants_ptr = nullptr; - int _constant_count = 0; - const StringName *_global_names_ptr = nullptr; - int _global_names_count = 0; - const int *_default_arg_ptr = nullptr; - int _default_arg_count = 0; - int _operator_funcs_count = 0; - const Variant::ValidatedOperatorEvaluator *_operator_funcs_ptr = nullptr; - int _setters_count = 0; - const Variant::ValidatedSetter *_setters_ptr = nullptr; - int _getters_count = 0; - const Variant::ValidatedGetter *_getters_ptr = nullptr; - int _keyed_setters_count = 0; - const Variant::ValidatedKeyedSetter *_keyed_setters_ptr = nullptr; - int _keyed_getters_count = 0; - const Variant::ValidatedKeyedGetter *_keyed_getters_ptr = nullptr; - int _indexed_setters_count = 0; - const Variant::ValidatedIndexedSetter *_indexed_setters_ptr = nullptr; - int _indexed_getters_count = 0; - const Variant::ValidatedIndexedGetter *_indexed_getters_ptr = nullptr; - int _builtin_methods_count = 0; - const Variant::ValidatedBuiltInMethod *_builtin_methods_ptr = nullptr; - int _constructors_count = 0; - const Variant::ValidatedConstructor *_constructors_ptr = nullptr; - int _utilities_count = 0; - const Variant::ValidatedUtilityFunction *_utilities_ptr = nullptr; - int _gds_utilities_count = 0; - const GDScriptUtilityFunctions::FunctionPtr *_gds_utilities_ptr = nullptr; - int _methods_count = 0; - MethodBind **_methods_ptr = nullptr; - int _lambdas_count = 0; - GDScriptFunction **_lambdas_ptr = nullptr; - int *_code_ptr = nullptr; - int _code_size = 0; + GDScript *_script = nullptr; + int _initial_line = 0; int _argument_count = 0; int _stack_size = 0; int _instruction_args_size = 0; - int _ptrcall_args_size = 0; - int _initial_line = 0; - bool _static = false; - Variant rpc_config; - - GDScript *_script = nullptr; + SelfList<GDScriptFunction> function_list{ this }; + mutable Variant nil; + HashMap<int, Variant::Type> temporary_slots; + List<StackDebug> stack_debug; - StringName name; + Vector<int> code; + Vector<int> default_arguments; Vector<Variant> constants; Vector<StringName> global_names; - Vector<int> default_arguments; Vector<Variant::ValidatedOperatorEvaluator> operator_funcs; Vector<Variant::ValidatedSetter> setters; Vector<Variant::ValidatedGetter> getters; @@ -503,18 +414,47 @@ private: Vector<GDScriptUtilityFunctions::FunctionPtr> gds_utilities; Vector<MethodBind *> methods; Vector<GDScriptFunction *> lambdas; - Vector<int> code; - Vector<GDScriptDataType> argument_types; - GDScriptDataType return_type; - HashMap<int, Variant::Type> temporary_slots; + int _code_size = 0; + int _default_arg_count = 0; + int _constant_count = 0; + int _global_names_count = 0; + int _operator_funcs_count = 0; + int _setters_count = 0; + int _getters_count = 0; + int _keyed_setters_count = 0; + int _keyed_getters_count = 0; + int _indexed_setters_count = 0; + int _indexed_getters_count = 0; + int _builtin_methods_count = 0; + int _constructors_count = 0; + int _utilities_count = 0; + int _gds_utilities_count = 0; + int _methods_count = 0; + int _lambdas_count = 0; -#ifdef TOOLS_ENABLED - Vector<StringName> arg_names; - Vector<Variant> default_arg_values; -#endif + int *_code_ptr = nullptr; + const int *_default_arg_ptr = nullptr; + mutable Variant *_constants_ptr = nullptr; + const StringName *_global_names_ptr = nullptr; + const Variant::ValidatedOperatorEvaluator *_operator_funcs_ptr = nullptr; + const Variant::ValidatedSetter *_setters_ptr = nullptr; + const Variant::ValidatedGetter *_getters_ptr = nullptr; + const Variant::ValidatedKeyedSetter *_keyed_setters_ptr = nullptr; + const Variant::ValidatedKeyedGetter *_keyed_getters_ptr = nullptr; + const Variant::ValidatedIndexedSetter *_indexed_setters_ptr = nullptr; + const Variant::ValidatedIndexedGetter *_indexed_getters_ptr = nullptr; + const Variant::ValidatedBuiltInMethod *_builtin_methods_ptr = nullptr; + const Variant::ValidatedConstructor *_constructors_ptr = nullptr; + const Variant::ValidatedUtilityFunction *_utilities_ptr = nullptr; + const GDScriptUtilityFunctions::FunctionPtr *_gds_utilities_ptr = nullptr; + MethodBind **_methods_ptr = nullptr; + GDScriptFunction **_lambdas_ptr = nullptr; #ifdef DEBUG_ENABLED + CharString func_cname; + const char *_func_cname = nullptr; + Vector<String> operator_names; Vector<String> setter_names; Vector<String> getter_names; @@ -522,20 +462,6 @@ private: Vector<String> constructors_names; Vector<String> utilities_names; Vector<String> gds_utilities_names; -#endif - - List<StackDebug> stack_debug; - - Variant _get_default_variant_for_data_type(const GDScriptDataType &p_data_type); - - _FORCE_INLINE_ String _get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const; - - friend class GDScriptLanguage; - - SelfList<GDScriptFunction> function_list{ this }; -#ifdef DEBUG_ENABLED - CharString func_cname; - const char *_func_cname = nullptr; struct Profile { StringName signature; @@ -548,10 +474,19 @@ private: uint64_t last_frame_call_count = 0; uint64_t last_frame_self_time = 0; uint64_t last_frame_total_time = 0; + typedef struct NativeProfile { + uint64_t call_count; + uint64_t total_time; + String signature; + } NativeProfile; + HashMap<String, NativeProfile> native_calls; + HashMap<String, NativeProfile> last_native_calls; } profile; - #endif + _FORCE_INLINE_ String _get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const; + Variant _get_default_variant_for_data_type(const GDScriptDataType &p_data_type); + public: static constexpr int MAX_CALL_DEPTH = 2048; // Limit to try to avoid crash because of a stack overflow. @@ -571,51 +506,25 @@ public: Variant result; }; + _FORCE_INLINE_ StringName get_name() const { return name; } + _FORCE_INLINE_ StringName get_source() const { return source; } + _FORCE_INLINE_ GDScript *get_script() const { return _script; } _FORCE_INLINE_ bool is_static() const { return _static; } + _FORCE_INLINE_ MethodInfo get_method_info() const { return method_info; } + _FORCE_INLINE_ Variant get_rpc_config() const { return rpc_config; } + _FORCE_INLINE_ int get_max_stack_size() const { return _stack_size; } - const int *get_code() const; //used for debug - int get_code_size() const; Variant get_constant(int p_idx) const; StringName get_global_name(int p_idx) const; - StringName get_name() const; - int get_max_stack_size() const; - int get_default_argument_count() const; - int get_default_argument_addr(int p_idx) const; - GDScriptDataType get_return_type() const; - GDScriptDataType get_argument_type(int p_idx) const; - GDScript *get_script() const { return _script; } - StringName get_source() const { return source; } - - void debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const; - - _FORCE_INLINE_ bool is_empty() const { return _code_size == 0; } - - int get_argument_count() const { return _argument_count; } - StringName get_argument_name(int p_idx) const { -#ifdef TOOLS_ENABLED - ERR_FAIL_INDEX_V(p_idx, arg_names.size(), StringName()); - return arg_names[p_idx]; -#else - return StringName(); -#endif - } - Variant get_default_argument(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, default_arguments.size(), Variant()); - return default_arguments[p_idx]; - } -#ifdef TOOLS_ENABLED - const Vector<Variant> &get_default_arg_values() const { - return default_arg_values; - } -#endif // TOOLS_ENABLED Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state = nullptr); + void debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const; #ifdef DEBUG_ENABLED + void _profile_native_call(uint64_t p_t_taken, const String &p_function_name, const String &p_instance_class_name = String()); void disassemble(const Vector<String> &p_code_lines) const; #endif - _FORCE_INLINE_ const Variant get_rpc_config() const { return rpc_config; } GDScriptFunction(); ~GDScriptFunction(); }; |