You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user