diff options
| author | George Marques <george@gmarqu.es> | 2021-05-16 11:48:53 -0300 |
|---|---|---|
| committer | George Marques <george@gmarqu.es> | 2021-05-16 11:54:33 -0300 |
| commit | ec783dd885a67467691ef3e55ca0d05151205c4c (patch) | |
| tree | 11af7a6fa2f744d4e56cd737b458c910ccdf1c5c /modules/gdscript/gdscript_byte_codegen.cpp | |
| parent | 6e621441ca0e562fb010c86d88e1d3a8a9ed0fd8 (diff) | |
| download | redot-engine-ec783dd885a67467691ef3e55ca0d05151205c4c.tar.gz | |
GDScript: Add support for builtin static method calls
Diffstat (limited to 'modules/gdscript/gdscript_byte_codegen.cpp')
| -rw-r--r-- | modules/gdscript/gdscript_byte_codegen.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 0da99ccee3..e3e88e5ed1 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -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++) { |
