Skip to content

Commit

Permalink
Merge pull request #94674 from dalexeev/gds-fix-incorrect-setter-call…
Browse files Browse the repository at this point in the history
…-for-ref-types

GDScript: Fix incorrect setter call for reference types
  • Loading branch information
akien-mga authored Jul 24, 2024
2 parents 543e438 + 8c82fd1 commit 77e18da
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 1 deletion.
10 changes: 9 additions & 1 deletion modules/gdscript/gdscript_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code

// Get at (potential) root stack pos, so it can be returned.
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) {
return GDScriptCodeGenerator::Address();
Expand All @@ -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.
// So use a temp value instead and call the setter at the end.
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);
gen->write_assign(base_temp, base);
prev_base = base_temp;
Expand Down Expand Up @@ -1229,8 +1231,14 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
}
}
} 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.
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 77e18da

Please sign in to comment.