You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
GDScript: Add speficic set/get instructions
When the base type is known at compile-time, we can get a direct function pointer that is faster than the regular set/get paths.
This commit is contained in:
@@ -170,6 +170,78 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() {
|
||||
function->_operator_funcs_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (setters_map.size()) {
|
||||
function->setters.resize(setters_map.size());
|
||||
function->_setters_count = function->setters.size();
|
||||
function->_setters_ptr = function->setters.ptr();
|
||||
for (const Map<Variant::ValidatedSetter, int>::Element *E = setters_map.front(); E; E = E->next()) {
|
||||
function->setters.write[E->get()] = E->key();
|
||||
}
|
||||
} else {
|
||||
function->_setters_count = 0;
|
||||
function->_setters_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (getters_map.size()) {
|
||||
function->getters.resize(getters_map.size());
|
||||
function->_getters_count = function->getters.size();
|
||||
function->_getters_ptr = function->getters.ptr();
|
||||
for (const Map<Variant::ValidatedGetter, int>::Element *E = getters_map.front(); E; E = E->next()) {
|
||||
function->getters.write[E->get()] = E->key();
|
||||
}
|
||||
} else {
|
||||
function->_getters_count = 0;
|
||||
function->_getters_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (keyed_setters_map.size()) {
|
||||
function->keyed_setters.resize(keyed_setters_map.size());
|
||||
function->_keyed_setters_count = function->keyed_setters.size();
|
||||
function->_keyed_setters_ptr = function->keyed_setters.ptr();
|
||||
for (const Map<Variant::ValidatedKeyedSetter, int>::Element *E = keyed_setters_map.front(); E; E = E->next()) {
|
||||
function->keyed_setters.write[E->get()] = E->key();
|
||||
}
|
||||
} else {
|
||||
function->_keyed_setters_count = 0;
|
||||
function->_keyed_setters_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (keyed_getters_map.size()) {
|
||||
function->keyed_getters.resize(keyed_getters_map.size());
|
||||
function->_keyed_getters_count = function->keyed_getters.size();
|
||||
function->_keyed_getters_ptr = function->keyed_getters.ptr();
|
||||
for (const Map<Variant::ValidatedKeyedGetter, int>::Element *E = keyed_getters_map.front(); E; E = E->next()) {
|
||||
function->keyed_getters.write[E->get()] = E->key();
|
||||
}
|
||||
} else {
|
||||
function->_keyed_getters_count = 0;
|
||||
function->_keyed_getters_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (indexed_setters_map.size()) {
|
||||
function->indexed_setters.resize(indexed_setters_map.size());
|
||||
function->_indexed_setters_count = function->indexed_setters.size();
|
||||
function->_indexed_setters_ptr = function->indexed_setters.ptr();
|
||||
for (const Map<Variant::ValidatedIndexedSetter, int>::Element *E = indexed_setters_map.front(); E; E = E->next()) {
|
||||
function->indexed_setters.write[E->get()] = E->key();
|
||||
}
|
||||
} else {
|
||||
function->_indexed_setters_count = 0;
|
||||
function->_indexed_setters_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (indexed_getters_map.size()) {
|
||||
function->indexed_getters.resize(indexed_getters_map.size());
|
||||
function->_indexed_getters_count = function->indexed_getters.size();
|
||||
function->_indexed_getters_ptr = function->indexed_getters.ptr();
|
||||
for (const Map<Variant::ValidatedIndexedGetter, int>::Element *E = indexed_getters_map.front(); E; E = E->next()) {
|
||||
function->indexed_getters.write[E->get()] = E->key();
|
||||
}
|
||||
} else {
|
||||
function->_indexed_getters_count = 0;
|
||||
function->_indexed_getters_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (debug_stack) {
|
||||
function->stack_debug = stack_debug;
|
||||
}
|
||||
@@ -193,6 +265,9 @@ void GDScriptByteCodeGenerator::set_initial_line(int p_line) {
|
||||
#define HAS_BUILTIN_TYPE(m_var) \
|
||||
(m_var.type.has_type && m_var.type.kind == GDScriptDataType::BUILTIN)
|
||||
|
||||
#define IS_BUILTIN_TYPE(m_var, m_type) \
|
||||
(m_var.type.has_type && m_var.type.kind == GDScriptDataType::BUILTIN && m_var.type.builtin_type == m_type)
|
||||
|
||||
void GDScriptByteCodeGenerator::write_operator(const Address &p_target, Variant::Operator p_operator, const Address &p_left_operand, const Address &p_right_operand) {
|
||||
if (HAS_BUILTIN_TYPE(p_left_operand) && HAS_BUILTIN_TYPE(p_right_operand)) {
|
||||
// Gather specific operator.
|
||||
@@ -324,20 +399,69 @@ void GDScriptByteCodeGenerator::write_end_ternary() {
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_set(const Address &p_target, const Address &p_index, const Address &p_source) {
|
||||
append(GDScriptFunction::OPCODE_SET, 3);
|
||||
if (HAS_BUILTIN_TYPE(p_target)) {
|
||||
if (IS_BUILTIN_TYPE(p_index, Variant::INT) && Variant::get_member_validated_indexed_setter(p_target.type.builtin_type)) {
|
||||
// Use indexed setter instead.
|
||||
Variant::ValidatedIndexedSetter setter = Variant::get_member_validated_indexed_setter(p_target.type.builtin_type);
|
||||
append(GDScriptFunction::OPCODE_SET_INDEXED_VALIDATED, 3);
|
||||
append(p_target);
|
||||
append(p_index);
|
||||
append(p_source);
|
||||
append(setter);
|
||||
return;
|
||||
} else if (Variant::get_member_validated_keyed_setter(p_target.type.builtin_type)) {
|
||||
Variant::ValidatedKeyedSetter setter = Variant::get_member_validated_keyed_setter(p_target.type.builtin_type);
|
||||
append(GDScriptFunction::OPCODE_SET_KEYED_VALIDATED, 3);
|
||||
append(p_target);
|
||||
append(p_index);
|
||||
append(p_source);
|
||||
append(setter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
append(GDScriptFunction::OPCODE_SET_KEYED, 3);
|
||||
append(p_target);
|
||||
append(p_index);
|
||||
append(p_source);
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_get(const Address &p_target, const Address &p_index, const Address &p_source) {
|
||||
append(GDScriptFunction::OPCODE_GET, 3);
|
||||
if (HAS_BUILTIN_TYPE(p_source)) {
|
||||
if (IS_BUILTIN_TYPE(p_index, Variant::INT) && Variant::get_member_validated_indexed_getter(p_source.type.builtin_type)) {
|
||||
// Use indexed getter instead.
|
||||
Variant::ValidatedIndexedGetter getter = Variant::get_member_validated_indexed_getter(p_source.type.builtin_type);
|
||||
append(GDScriptFunction::OPCODE_GET_INDEXED_VALIDATED, 3);
|
||||
append(p_source);
|
||||
append(p_index);
|
||||
append(p_target);
|
||||
append(getter);
|
||||
return;
|
||||
} else if (Variant::get_member_validated_keyed_getter(p_source.type.builtin_type)) {
|
||||
Variant::ValidatedKeyedGetter getter = Variant::get_member_validated_keyed_getter(p_source.type.builtin_type);
|
||||
append(GDScriptFunction::OPCODE_GET_KEYED_VALIDATED, 3);
|
||||
append(p_source);
|
||||
append(p_index);
|
||||
append(p_target);
|
||||
append(getter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
append(GDScriptFunction::OPCODE_GET_KEYED, 3);
|
||||
append(p_source);
|
||||
append(p_index);
|
||||
append(p_target);
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_set_named(const Address &p_target, const StringName &p_name, const Address &p_source) {
|
||||
if (HAS_BUILTIN_TYPE(p_target) && Variant::get_member_validated_setter(p_target.type.builtin_type, p_name)) {
|
||||
Variant::ValidatedSetter setter = Variant::get_member_validated_setter(p_target.type.builtin_type, p_name);
|
||||
append(GDScriptFunction::OPCODE_SET_NAMED_VALIDATED, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
append(setter);
|
||||
return;
|
||||
}
|
||||
append(GDScriptFunction::OPCODE_SET_NAMED, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
@@ -345,6 +469,14 @@ void GDScriptByteCodeGenerator::write_set_named(const Address &p_target, const S
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_get_named(const Address &p_target, const StringName &p_name, const Address &p_source) {
|
||||
if (HAS_BUILTIN_TYPE(p_source) && Variant::get_member_validated_getter(p_source.type.builtin_type, p_name)) {
|
||||
Variant::ValidatedGetter getter = Variant::get_member_validated_getter(p_source.type.builtin_type, p_name);
|
||||
append(GDScriptFunction::OPCODE_GET_NAMED_VALIDATED, 2);
|
||||
append(p_source);
|
||||
append(p_target);
|
||||
append(getter);
|
||||
return;
|
||||
}
|
||||
append(GDScriptFunction::OPCODE_GET_NAMED, 2);
|
||||
append(p_source);
|
||||
append(p_target);
|
||||
|
||||
Reference in New Issue
Block a user