From bdd5f52a511dfc7a7475340802df19f95d752487 Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Sun, 22 Jan 2012 20:27:16 +0100 Subject: [PATCH] Initialize the variable directly when assigning a struct creation Some structs like WeakRef or potentially Mutex can't use temporary variables during initialization. --- codegen/valaccodeassignmentmodule.vala | 2 ++ codegen/valaccodebasemodule.vala | 38 +++++++++++++++++++------- vala/valaassignment.vala | 3 +- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala index 47985a1d0..b25bd8dd2 100644 --- a/codegen/valaccodeassignmentmodule.vala +++ b/codegen/valaccodeassignmentmodule.vala @@ -87,6 +87,8 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule { store_property (prop, ma.inner, assignment.right.target_value); assignment.target_value = assignment.right.target_value; + } else if (assignment.left.symbol_reference is Variable && is_simple_struct_creation ((Variable) assignment.left.symbol_reference, assignment.right)) { + // delegate to visit_object_creation_expression } else { assignment.target_value = emit_simple_assignment (assignment); } diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 122e0c644..f43ff7226 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -2149,11 +2149,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } } - bool has_simple_struct_initializer (LocalVariable local) { - var st = local.variable_type.data_type as Struct; - var initializer = local.initializer as ObjectCreationExpression; - if (st != null && (!st.is_simple_type () || get_ccode_name (st) == "va_list") && !local.variable_type.nullable && - local.variable_type.data_type != gvalue_type && initializer != null && initializer.get_object_initializer ().size == 0) { + public bool is_simple_struct_creation (Variable variable, Expression expr) { + var st = variable.variable_type.data_type as Struct; + var creation = expr as ObjectCreationExpression; + if (creation != null && st != null && (!st.is_simple_type () || get_ccode_name (st) == "va_list") && !variable.variable_type.nullable && + variable.variable_type.data_type != gvalue_type && creation.get_object_initializer ().size == 0) { return true; } else { return false; @@ -2190,7 +2190,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { // try to initialize uninitialized variables // initialization not necessary for variables stored in closure - if (rhs == null || has_simple_struct_initializer (local)) { + if (rhs == null || is_simple_struct_creation (local, local.initializer)) { cvar.initializer = default_value_for_type (local.variable_type, true); cvar.init0 = true; } @@ -2233,7 +2233,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } if (rhs != null) { - if (!has_simple_struct_initializer (local)) { + if (!is_simple_struct_creation (local, local.initializer)) { store_local (local, local.initializer.target_value, true); } } @@ -3217,7 +3217,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } var local_decl = expr.parent_node as LocalVariable; - if (!(local_decl != null && has_simple_struct_initializer (local_decl))) { + if (!(local_decl != null && is_simple_struct_creation (local_decl, local_decl.initializer))) { expr.target_value = store_temp_value (expr.target_value, expr); } @@ -4251,8 +4251,26 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { // value-type initialization or object creation expression with object initializer var local = expr.parent_node as LocalVariable; - if (local != null && has_simple_struct_initializer (local)) { + var a = expr.parent_node as Assignment; + if (local != null && is_simple_struct_creation (local, local.initializer)) { instance = get_cvalue_ (get_local_cvalue (local)); + } else if (a != null && a.left.symbol_reference is Variable && is_simple_struct_creation ((Variable) a.left.symbol_reference, a.right)) { + if (requires_destroy (a.left.value_type)) { + /* unref old value */ + ccode.add_expression (destroy_value (a.left.target_value)); + } + + local = a.left.symbol_reference as LocalVariable; + var field = a.left.symbol_reference as Field; + var param = a.left.symbol_reference as Parameter; + if (local != null) { + instance = get_cvalue_ (get_local_cvalue (local)); + } else if (field != null) { + var inner = ((MemberAccess) a.left).inner; + instance = get_cvalue_ (get_field_cvalue (field, inner != null ? inner.target_value : null)); + } else if (param != null) { + instance = get_cvalue_ (get_parameter_cvalue (param)); + } } else { var temp_value = create_temp_value (expr.type_reference, true, expr); instance = get_cvalue_ (temp_value); @@ -4475,7 +4493,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } var local = expr.parent_node as LocalVariable; - if (local != null && has_simple_struct_initializer (local)) { + if (local != null && is_simple_struct_creation (local, local.initializer)) { // no temporary variable necessary ccode.add_expression (creation_expr); set_cvalue (expr, instance); diff --git a/vala/valaassignment.vala b/vala/valaassignment.vala index d88c3e073..87281ad30 100644 --- a/vala/valaassignment.vala +++ b/vala/valaassignment.vala @@ -472,7 +472,8 @@ public class Vala.Assignment : Expression { if (operator == AssignmentOperator.SIMPLE && (local != null || param != null || field != null) && !is_array_add () && - !(field is ArrayLengthField)) { + !(field is ArrayLengthField) && + !(left.value_type.is_real_non_null_struct_type () && right is ObjectCreationExpression)) { // visit_assignment not necessary if (instance && ma.inner != null) { ma.inner.emit (codegen); -- 2.47.2