GDScript: Add support for builtin static method calls

This commit is contained in:
George Marques 2021-05-16 11:48:53 -03:00
parent 6e621441ca
commit ec783dd885
No known key found for this signature in database
GPG key ID: 046BD46A3201E43D
8 changed files with 169 additions and 29 deletions

View file

@ -1017,6 +1017,56 @@ void GDScriptByteCodeGenerator::write_call_builtin_type(const Address &p_target,
append(Variant::get_validated_builtin_method(p_type, p_method));
}
void GDScriptByteCodeGenerator::write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) {
bool is_validated = false;
// Check if all types are correct.
if (Variant::is_builtin_method_vararg(p_type, p_method)) {
is_validated = true; // Vararg works fine with any argument, since they can be any type.
} else if (p_arguments.size() == Variant::get_builtin_method_argument_count(p_type, p_method)) {
bool all_types_exact = true;
for (int i = 0; i < p_arguments.size(); i++) {
if (!IS_BUILTIN_TYPE(p_arguments[i], Variant::get_builtin_method_argument_type(p_type, p_method, i))) {
all_types_exact = false;
break;
}
}
is_validated = all_types_exact;
}
if (!is_validated) {
// Perform regular call.
append(GDScriptFunction::OPCODE_CALL_BUILTIN_STATIC, p_arguments.size() + 1);
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
append(p_target);
append(p_type);
append(p_method);
append(p_arguments.size());
return;
}
if (p_target.mode == Address::TEMPORARY) {
Variant::Type result_type = Variant::get_builtin_method_return_type(p_type, p_method);
Variant::Type temp_type = temporaries[p_target.address].type;
if (result_type != temp_type) {
write_type_adjust(p_target, result_type);
}
}
append(GDScriptFunction::OPCODE_CALL_BUILTIN_TYPE_VALIDATED, 2 + p_arguments.size());
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
append(Address()); // No base since it's static.
append(p_target);
append(p_arguments.size());
append(Variant::get_validated_builtin_method(p_type, p_method));
}
void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL_METHOD_BIND : GDScriptFunction::OPCODE_CALL_METHOD_BIND_RET, 2 + p_arguments.size());
for (int i = 0; i < p_arguments.size(); i++) {