GDScript: Perform validated calls with static methods

When the types are validated at compile time, this type of call runs
faster. It is already used for instance methods, this adds this
optimization to native static methods as well.
This commit is contained in:
George Marques 2024-04-25 21:05:53 -03:00
parent 11d3768132
commit 7ca038effa
No known key found for this signature in database
GPG key ID: 046BD46A3201E43D
9 changed files with 330 additions and 165 deletions

View file

@ -1196,23 +1196,49 @@ void GDScriptByteCodeGenerator::write_call_builtin_type_static(const Address &p_
}
void GDScriptByteCodeGenerator::write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) {
bool is_validated = false;
MethodBind *method = ClassDB::get_method(p_class, p_method);
if (!is_validated) {
// Perform regular call.
append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_NATIVE_STATIC, p_arguments.size() + 1);
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
CallTarget ct = get_call_target(p_target);
append(ct.target);
append(method);
append(p_arguments.size());
ct.cleanup();
return;
// Perform regular call.
append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_NATIVE_STATIC, p_arguments.size() + 1);
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
CallTarget ct = get_call_target(p_target);
append(ct.target);
append(method);
append(p_arguments.size());
ct.cleanup();
return;
}
void GDScriptByteCodeGenerator::write_call_native_static_validated(const GDScriptCodeGenerator::Address &p_target, MethodBind *p_method, const Vector<GDScriptCodeGenerator::Address> &p_arguments) {
Variant::Type return_type = Variant::NIL;
bool has_return = p_method->has_return();
if (has_return) {
PropertyInfo return_info = p_method->get_return_info();
return_type = return_info.type;
}
CallTarget ct = get_call_target(p_target, return_type);
if (has_return) {
Variant::Type temp_type = temporaries[ct.target.address].type;
if (temp_type != return_type) {
write_type_adjust(ct.target, return_type);
}
}
GDScriptFunction::Opcode code = p_method->has_return() ? GDScriptFunction::OPCODE_CALL_NATIVE_STATIC_VALIDATED_RETURN : GDScriptFunction::OPCODE_CALL_NATIVE_STATIC_VALIDATED_NO_RETURN;
append_opcode_and_argcount(code, 1 + p_arguments.size());
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
append(ct.target);
append(p_arguments.size());
append(p_method);
ct.cleanup();
}
void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {