From 5518e2a68e36fe8a9dcf1531228a7b3cc4411263 Mon Sep 17 00:00:00 2001 From: George Marques Date: Wed, 18 Nov 2020 11:37:08 -0300 Subject: GDScript: Add faster instruction for validated constructor Only for built-in types. --- modules/gdscript/gdscript_byte_codegen.cpp | 54 +++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'modules/gdscript/gdscript_byte_codegen.cpp') diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 5772f8bce3..5f1c738207 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -244,7 +244,7 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { if (builtin_method_map.size()) { function->builtin_methods.resize(builtin_method_map.size()); - function->_builtin_methods_ptr = function->builtin_methods.ptrw(); + function->_builtin_methods_ptr = function->builtin_methods.ptr(); function->_builtin_methods_count = builtin_method_map.size(); for (const Map::Element *E = builtin_method_map.front(); E; E = E->next()) { function->builtin_methods.write[E->get()] = E->key(); @@ -254,6 +254,18 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->_builtin_methods_count = 0; } + if (constructors_map.size()) { + function->constructors.resize(constructors_map.size()); + function->_constructors_ptr = function->constructors.ptr(); + function->_constructors_count = constructors_map.size(); + for (const Map::Element *E = constructors_map.front(); E; E = E->next()) { + function->constructors.write[E->get()] = E->key(); + } + } else { + function->_constructors_ptr = nullptr; + function->_constructors_count = 0; + } + if (method_bind_map.size()) { function->methods.resize(method_bind_map.size()); function->_methods_ptr = function->methods.ptrw(); @@ -797,6 +809,46 @@ void GDScriptByteCodeGenerator::write_call_script_function(const Address &p_targ } void GDScriptByteCodeGenerator::write_construct(const Address &p_target, Variant::Type p_type, const Vector
&p_arguments) { + // Try to find an appropriate constructor. + bool all_have_type = true; + Vector arg_types; + for (int i = 0; i < p_arguments.size(); i++) { + if (!HAS_BUILTIN_TYPE(p_arguments[i])) { + all_have_type = false; + break; + } + arg_types.push_back(p_arguments[i].type.builtin_type); + } + if (all_have_type) { + int valid_constructor = -1; + for (int i = 0; i < Variant::get_constructor_count(p_type); i++) { + if (Variant::get_constructor_argument_count(p_type, i) != p_arguments.size()) { + continue; + } + int types_correct = true; + for (int j = 0; j < arg_types.size(); j++) { + if (arg_types[j] != Variant::get_constructor_argument_type(p_type, i, j)) { + types_correct = false; + break; + } + } + if (types_correct) { + valid_constructor = i; + break; + } + } + if (valid_constructor >= 0) { + append(GDScriptFunction::OPCODE_CONSTRUCT_VALIDATED, 1 + p_arguments.size()); + for (int i = 0; i < p_arguments.size(); i++) { + append(p_arguments[i]); + } + append(p_target); + append(p_arguments.size()); + append(Variant::get_validated_constructor(p_type, valid_constructor)); + return; + } + } + append(GDScriptFunction::OPCODE_CONSTRUCT, 1 + p_arguments.size()); for (int i = 0; i < p_arguments.size(); i++) { append(p_arguments[i]); -- cgit v1.2.3