diff options
Diffstat (limited to 'modules/gdscript/gdscript_byte_codegen.cpp')
-rw-r--r-- | modules/gdscript/gdscript_byte_codegen.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 4cda3d3037..b77c641eb5 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -634,6 +634,18 @@ void GDScriptByteCodeGenerator::write_type_test(const Address &p_target, const A append(get_constant_pos(element_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); append(element_type.builtin_type); append(element_type.native_type); + } else if (p_type.builtin_type == Variant::DICTIONARY && p_type.has_container_element_types()) { + const GDScriptDataType &key_element_type = p_type.get_container_element_type_or_variant(0); + const GDScriptDataType &value_element_type = p_type.get_container_element_type_or_variant(1); + append_opcode(GDScriptFunction::OPCODE_TYPE_TEST_DICTIONARY); + append(p_target); + append(p_source); + append(get_constant_pos(key_element_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(get_constant_pos(value_element_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(key_element_type.builtin_type); + append(key_element_type.native_type); + append(value_element_type.builtin_type); + append(value_element_type.native_type); } else { append_opcode(GDScriptFunction::OPCODE_TYPE_TEST_BUILTIN); append(p_target); @@ -889,6 +901,18 @@ void GDScriptByteCodeGenerator::write_assign_with_conversion(const Address &p_ta append(get_constant_pos(element_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); append(element_type.builtin_type); append(element_type.native_type); + } else if (p_target.type.builtin_type == Variant::DICTIONARY && p_target.type.has_container_element_types()) { + const GDScriptDataType &key_type = p_target.type.get_container_element_type_or_variant(0); + const GDScriptDataType &value_type = p_target.type.get_container_element_type_or_variant(1); + append_opcode(GDScriptFunction::OPCODE_ASSIGN_TYPED_DICTIONARY); + append(p_target); + append(p_source); + append(get_constant_pos(key_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(get_constant_pos(value_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(key_type.builtin_type); + append(key_type.native_type); + append(value_type.builtin_type); + append(value_type.native_type); } else { append_opcode(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); append(p_target); @@ -935,6 +959,18 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr append(get_constant_pos(element_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); append(element_type.builtin_type); append(element_type.native_type); + } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::DICTIONARY && p_target.type.has_container_element_types()) { + const GDScriptDataType &key_type = p_target.type.get_container_element_type_or_variant(0); + const GDScriptDataType &value_type = p_target.type.get_container_element_type_or_variant(1); + append_opcode(GDScriptFunction::OPCODE_ASSIGN_TYPED_DICTIONARY); + append(p_target); + append(p_source); + append(get_constant_pos(key_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(get_constant_pos(value_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(key_type.builtin_type); + append(key_type.native_type); + append(value_type.builtin_type); + append(value_type.native_type); } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) { // Need conversion. append_opcode(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); @@ -1434,6 +1470,23 @@ void GDScriptByteCodeGenerator::write_construct_dictionary(const Address &p_targ ct.cleanup(); } +void GDScriptByteCodeGenerator::write_construct_typed_dictionary(const Address &p_target, const GDScriptDataType &p_key_type, const GDScriptDataType &p_value_type, const Vector<Address> &p_arguments) { + append_opcode_and_argcount(GDScriptFunction::OPCODE_CONSTRUCT_TYPED_DICTIONARY, 3 + p_arguments.size()); + for (int i = 0; i < p_arguments.size(); i++) { + append(p_arguments[i]); + } + CallTarget ct = get_call_target(p_target); + append(ct.target); + append(get_constant_pos(p_key_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(get_constant_pos(p_value_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(p_arguments.size() / 2); // This is number of key-value pairs, so only half of actual arguments. + append(p_key_type.builtin_type); + append(p_key_type.native_type); + append(p_value_type.builtin_type); + append(p_value_type.native_type); + ct.cleanup(); +} + void GDScriptByteCodeGenerator::write_await(const Address &p_target, const Address &p_operand) { append_opcode(GDScriptFunction::OPCODE_AWAIT); append(p_operand); @@ -1711,6 +1764,19 @@ void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) { append(get_constant_pos(element_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); append(element_type.builtin_type); append(element_type.native_type); + } else if (function->return_type.kind == GDScriptDataType::BUILTIN && function->return_type.builtin_type == Variant::DICTIONARY && + function->return_type.has_container_element_types()) { + // Typed dictionary. + const GDScriptDataType &key_type = function->return_type.get_container_element_type_or_variant(0); + const GDScriptDataType &value_type = function->return_type.get_container_element_type_or_variant(1); + append_opcode(GDScriptFunction::OPCODE_RETURN_TYPED_DICTIONARY); + append(p_return_value); + append(get_constant_pos(key_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(get_constant_pos(value_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(key_type.builtin_type); + append(key_type.native_type); + append(value_type.builtin_type); + append(value_type.native_type); } else if (function->return_type.kind == GDScriptDataType::BUILTIN && p_return_value.type.kind == GDScriptDataType::BUILTIN && function->return_type.builtin_type != p_return_value.type.builtin_type) { // Add conversion. append_opcode(GDScriptFunction::OPCODE_RETURN_TYPED_BUILTIN); @@ -1735,6 +1801,17 @@ void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) { append(get_constant_pos(element_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); append(element_type.builtin_type); append(element_type.native_type); + } else if (function->return_type.builtin_type == Variant::DICTIONARY && function->return_type.has_container_element_types()) { + const GDScriptDataType &key_type = function->return_type.get_container_element_type_or_variant(0); + const GDScriptDataType &value_type = function->return_type.get_container_element_type_or_variant(1); + append_opcode(GDScriptFunction::OPCODE_RETURN_TYPED_DICTIONARY); + append(p_return_value); + append(get_constant_pos(key_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(get_constant_pos(value_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS)); + append(key_type.builtin_type); + append(key_type.native_type); + append(value_type.builtin_type); + append(value_type.native_type); } else { append_opcode(GDScriptFunction::OPCODE_RETURN_TYPED_BUILTIN); append(p_return_value); @@ -1803,6 +1880,13 @@ void GDScriptByteCodeGenerator::clear_address(const Address &p_address) { case Variant::BOOL: write_assign_false(p_address); break; + case Variant::DICTIONARY: + if (p_address.type.has_container_element_types()) { + write_construct_typed_dictionary(p_address, p_address.type.get_container_element_type_or_variant(0), p_address.type.get_container_element_type_or_variant(1), Vector<GDScriptCodeGenerator::Address>()); + } else { + write_construct(p_address, p_address.type.builtin_type, Vector<GDScriptCodeGenerator::Address>()); + } + break; case Variant::ARRAY: if (p_address.type.has_container_element_type(0)) { write_construct_typed_array(p_address, p_address.type.get_container_element_type(0), Vector<GDScriptCodeGenerator::Address>()); |