Merge pull request #94674 from dalexeev/gds-fix-incorrect-setter-call-for-ref-types
GDScript: Fix incorrect setter call for reference types
This commit is contained in:
commit
77e18da5ff
3 changed files with 97 additions and 1 deletions
|
@ -1064,6 +1064,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
||||||
|
|
||||||
// Get at (potential) root stack pos, so it can be returned.
|
// Get at (potential) root stack pos, so it can be returned.
|
||||||
GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, chain.back()->get()->base);
|
GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, chain.back()->get()->base);
|
||||||
|
const bool base_known_type = base.type.has_type;
|
||||||
|
const bool base_is_shared = Variant::is_type_shared(base.type.builtin_type);
|
||||||
|
|
||||||
if (r_error) {
|
if (r_error) {
|
||||||
return GDScriptCodeGenerator::Address();
|
return GDScriptCodeGenerator::Address();
|
||||||
|
@ -1074,7 +1076,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
||||||
// In case the base has a setter, don't use the address directly, as we want to call that setter.
|
// In case the base has a setter, don't use the address directly, as we want to call that setter.
|
||||||
// So use a temp value instead and call the setter at the end.
|
// So use a temp value instead and call the setter at the end.
|
||||||
GDScriptCodeGenerator::Address base_temp;
|
GDScriptCodeGenerator::Address base_temp;
|
||||||
if (base.mode == GDScriptCodeGenerator::Address::MEMBER && member_property_has_setter && !member_property_is_in_setter) {
|
if ((!base_known_type || !base_is_shared) && base.mode == GDScriptCodeGenerator::Address::MEMBER && member_property_has_setter && !member_property_is_in_setter) {
|
||||||
base_temp = codegen.add_temporary(base.type);
|
base_temp = codegen.add_temporary(base.type);
|
||||||
gen->write_assign(base_temp, base);
|
gen->write_assign(base_temp, base);
|
||||||
prev_base = base_temp;
|
prev_base = base_temp;
|
||||||
|
@ -1229,8 +1231,14 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (base_temp.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
} else if (base_temp.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
||||||
|
if (!base_known_type) {
|
||||||
|
gen->write_jump_if_shared(base);
|
||||||
|
}
|
||||||
// Save the temp value back to the base by calling its setter.
|
// Save the temp value back to the base by calling its setter.
|
||||||
gen->write_call(GDScriptCodeGenerator::Address(), base, member_property_setter_function, { assigned });
|
gen->write_call(GDScriptCodeGenerator::Address(), base, member_property_setter_function, { assigned });
|
||||||
|
if (!base_known_type) {
|
||||||
|
gen->write_end_jump_if_shared();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
# GH-94667
|
||||||
|
|
||||||
|
class Inner:
|
||||||
|
var subprop: Vector2:
|
||||||
|
set(value):
|
||||||
|
prints("subprop setter", value)
|
||||||
|
subprop = value
|
||||||
|
get:
|
||||||
|
print("subprop getter")
|
||||||
|
return subprop
|
||||||
|
|
||||||
|
func _to_string() -> String:
|
||||||
|
return "<Inner>"
|
||||||
|
|
||||||
|
var prop1:
|
||||||
|
set(value):
|
||||||
|
prints("prop1 setter", value)
|
||||||
|
prop1 = value
|
||||||
|
|
||||||
|
var prop2: Inner:
|
||||||
|
set(value):
|
||||||
|
prints("prop2 setter", value)
|
||||||
|
prop2 = value
|
||||||
|
|
||||||
|
var prop3:
|
||||||
|
set(value):
|
||||||
|
prints("prop3 setter", value)
|
||||||
|
prop3 = value
|
||||||
|
get:
|
||||||
|
print("prop3 getter")
|
||||||
|
return prop3
|
||||||
|
|
||||||
|
var prop4: Inner:
|
||||||
|
set(value):
|
||||||
|
prints("prop4 setter", value)
|
||||||
|
prop4 = value
|
||||||
|
get:
|
||||||
|
print("prop4 getter")
|
||||||
|
return prop4
|
||||||
|
|
||||||
|
func test():
|
||||||
|
print("===")
|
||||||
|
prop1 = Vector2()
|
||||||
|
prop1.x = 1.0
|
||||||
|
print("---")
|
||||||
|
prop1 = Inner.new()
|
||||||
|
prop1.subprop.x = 1.0
|
||||||
|
|
||||||
|
print("===")
|
||||||
|
prop2 = Inner.new()
|
||||||
|
prop2.subprop.x = 1.0
|
||||||
|
|
||||||
|
print("===")
|
||||||
|
prop3 = Vector2()
|
||||||
|
prop3.x = 1.0
|
||||||
|
print("---")
|
||||||
|
prop3 = Inner.new()
|
||||||
|
prop3.subprop.x = 1.0
|
||||||
|
|
||||||
|
print("===")
|
||||||
|
prop4 = Inner.new()
|
||||||
|
prop4.subprop.x = 1.0
|
|
@ -0,0 +1,26 @@
|
||||||
|
GDTEST_OK
|
||||||
|
===
|
||||||
|
prop1 setter (0, 0)
|
||||||
|
prop1 setter (1, 0)
|
||||||
|
---
|
||||||
|
prop1 setter <Inner>
|
||||||
|
subprop getter
|
||||||
|
subprop setter (1, 0)
|
||||||
|
===
|
||||||
|
prop2 setter <Inner>
|
||||||
|
subprop getter
|
||||||
|
subprop setter (1, 0)
|
||||||
|
===
|
||||||
|
prop3 setter (0, 0)
|
||||||
|
prop3 getter
|
||||||
|
prop3 setter (1, 0)
|
||||||
|
---
|
||||||
|
prop3 setter <Inner>
|
||||||
|
prop3 getter
|
||||||
|
subprop getter
|
||||||
|
subprop setter (1, 0)
|
||||||
|
===
|
||||||
|
prop4 setter <Inner>
|
||||||
|
prop4 getter
|
||||||
|
subprop getter
|
||||||
|
subprop setter (1, 0)
|
Loading…
Reference in a new issue