GDScript: Add faster instruction for validated constructor

Only for built-in types.
This commit is contained in:
George Marques 2020-11-18 11:37:08 -03:00
parent e0dca3c6b6
commit 5518e2a68e
No known key found for this signature in database
GPG key ID: 046BD46A3201E43D
5 changed files with 112 additions and 3 deletions

View file

@ -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]);