mirror of
https://github.com/godotengine/godot.git
synced 2025-10-20 00:13:30 +00:00
GDScript: Use analyzer data to decide assignment conversion
Since there might be tricky cases in the analyzer (in the case of unsafe lines) which would need to be properly checked again. Instead, this splits the code generator in two functions and use information set by the analyzer to tell which function to use, without a need to re-check.
This commit is contained in:
parent
313e1f62bb
commit
c7459e3855
6 changed files with 74 additions and 51 deletions
|
@ -779,63 +779,43 @@ void GDScriptByteCodeGenerator::write_get_member(const Address &p_target, const
|
|||
append(p_name);
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) {
|
||||
if (p_target.type.has_type && !p_source.type.has_type) {
|
||||
// Typed assignment.
|
||||
switch (p_target.type.kind) {
|
||||
case GDScriptDataType::BUILTIN: {
|
||||
if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
} else {
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
append(p_target.type.builtin_type);
|
||||
}
|
||||
} break;
|
||||
case GDScriptDataType::NATIVE: {
|
||||
int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type];
|
||||
Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
|
||||
class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3);
|
||||
void GDScriptByteCodeGenerator::write_assign_with_conversion(const Address &p_target, const Address &p_source) {
|
||||
switch (p_target.type.kind) {
|
||||
case GDScriptDataType::BUILTIN: {
|
||||
if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
append(class_idx);
|
||||
} break;
|
||||
case GDScriptDataType::SCRIPT:
|
||||
case GDScriptDataType::GDSCRIPT: {
|
||||
Variant script = p_target.type.script_type;
|
||||
int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
|
||||
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
append(idx);
|
||||
} break;
|
||||
default: {
|
||||
ERR_PRINT("Compiler bug: unresolved assign.");
|
||||
|
||||
// Shouldn't get here, but fail-safe to a regular assignment
|
||||
append(GDScriptFunction::OPCODE_ASSIGN, 2);
|
||||
} else {
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
append(p_target.type.builtin_type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
|
||||
} break;
|
||||
case GDScriptDataType::NATIVE: {
|
||||
int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type];
|
||||
Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
|
||||
class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
} 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(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
|
||||
append(class_idx);
|
||||
} break;
|
||||
case GDScriptDataType::SCRIPT:
|
||||
case GDScriptDataType::GDSCRIPT: {
|
||||
Variant script = p_target.type.script_type;
|
||||
int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
|
||||
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
append(p_target.type.builtin_type);
|
||||
} else {
|
||||
// Either untyped assignment or already type-checked by the parser
|
||||
append(idx);
|
||||
} break;
|
||||
default: {
|
||||
ERR_PRINT("Compiler bug: unresolved assign.");
|
||||
|
||||
// Shouldn't get here, but fail-safe to a regular assignment
|
||||
append(GDScriptFunction::OPCODE_ASSIGN, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
|
@ -843,6 +823,24 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr
|
|||
}
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) {
|
||||
if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
} 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(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
append(p_target.type.builtin_type);
|
||||
} else {
|
||||
append(GDScriptFunction::OPCODE_ASSIGN, 2);
|
||||
append(p_target);
|
||||
append(p_source);
|
||||
}
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_assign_true(const Address &p_target) {
|
||||
append(GDScriptFunction::OPCODE_ASSIGN_TRUE, 1);
|
||||
append(p_target);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue