|
@@ -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) {
|