summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/gdscript_byte_codegen.cpp
diff options
context:
space:
mode:
authorGeorge Marques <george@gmarqu.es>2020-11-18 11:37:08 -0300
committerGeorge Marques <george@gmarqu.es>2020-11-21 13:30:17 -0300
commit5518e2a68e36fe8a9dcf1531228a7b3cc4411263 (patch)
treed0790c288e54056f5a480d43fe88819535c1fa39 /modules/gdscript/gdscript_byte_codegen.cpp
parente0dca3c6b6f0a4dc0126c45873ff4c8c30e2d8a0 (diff)
downloadredot-engine-5518e2a68e36fe8a9dcf1531228a7b3cc4411263.tar.gz
GDScript: Add faster instruction for validated constructor
Only for built-in types.
Diffstat (limited to 'modules/gdscript/gdscript_byte_codegen.cpp')
-rw-r--r--modules/gdscript/gdscript_byte_codegen.cpp54
1 files changed, 53 insertions, 1 deletions
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<Variant::ValidatedBuiltInMethod, int>::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<Variant::ValidatedConstructor, int>::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<Address> &p_arguments) {
+ // Try to find an appropriate constructor.
+ bool all_have_type = true;
+ Vector<Variant::Type> 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]);