[vala/emit-let: 4/10] codegen: Introduce emit_local and use store_local for visit_local_variable.



commit df2043a07449fff60f3b97eb38a5e7d0b92b91fd
Author: Luca Bruno <lucabru src gnome org>
Date:   Mon Jan 17 17:58:26 2011 +0100

    codegen: Introduce emit_local and use store_local for visit_local_variable.

 codegen/valaccodeassignmentmodule.vala |   44 ++++--
 codegen/valaccodebasemodule.vala       |  242 ++++++++------------------------
 codegen/valadovaassignmentmodule.vala  |    6 +-
 vala/valacodegenerator.vala            |    2 +-
 4 files changed, 95 insertions(+), 199 deletions(-)
---
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala
index 9c53c5a..cf8e217 100644
--- a/codegen/valaccodeassignmentmodule.vala
+++ b/codegen/valaccodeassignmentmodule.vala
@@ -171,8 +171,8 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
 		}
 	}
 
-	void store_variable (Variable variable, TargetValue lvalue, TargetValue value) {
-		if (requires_destroy (variable.variable_type)) {
+	void store_variable (Variable variable, TargetValue lvalue, TargetValue value, bool initializer) {
+		if (!initializer && requires_destroy (variable.variable_type)) {
 			/* unref old value */
 			ccode.add_expression (destroy_value (lvalue));
 		}
@@ -181,17 +181,33 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
 
 		var array_type = variable.variable_type as ArrayType;
 		if (array_type != null) {
-			for (int dim = 1; dim <= array_type.rank; dim++) {
-				if (get_array_length_cvalue (lvalue, dim) != null) {
-					ccode.add_assignment (get_array_length_cvalue (lvalue, dim), get_array_length_cvalue (value, dim));
+			if (array_type.fixed_length) {
+				cfile.add_include ("string.h");
+
+				// it is necessary to use memcpy for fixed-length (stack-allocated) arrays
+				// simple assignments do not work in C
+				var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+				sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
+				var size = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("%d".printf (array_type.length)), sizeof_call);
+
+				var ccopy = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+				ccopy.add_argument (get_cvalue_ (lvalue));
+				ccopy.add_argument (get_cvalue_ (value));
+				ccopy.add_argument (size);
+				ccode.add_expression (ccopy);
+			} else {
+				for (int dim = 1; dim <= array_type.rank; dim++) {
+					if (get_array_length_cvalue (lvalue, dim) != null) {
+						ccode.add_assignment (get_array_length_cvalue (lvalue, dim), get_array_length_cvalue (value, dim));
+					}
 				}
-			}
-			if (array_type.rank == 1) {
-				if (get_array_size_cvalue (lvalue) != null) {
-					if (get_array_size_cvalue (value) != null) {
-						ccode.add_assignment (get_array_size_cvalue (lvalue), get_array_size_cvalue (value));
-					} else {
-						ccode.add_assignment (get_array_size_cvalue (lvalue), get_array_length_cvalue (value, 1));
+				if (array_type.rank == 1) {
+					if (get_array_size_cvalue (lvalue) != null) {
+						if (get_array_size_cvalue (value) != null) {
+							ccode.add_assignment (get_array_size_cvalue (lvalue), get_array_size_cvalue (value));
+						} else {
+							ccode.add_assignment (get_array_size_cvalue (lvalue), get_array_length_cvalue (value, 1));
+						}
 					}
 				}
 			}
@@ -208,7 +224,7 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
 		}
 	}
 
-	public override void store_local (LocalVariable local, TargetValue value) {
-		store_variable (local, get_local_cvalue (local), value);
+	public override void store_local (LocalVariable local, TargetValue value, bool initializer) {
+		store_variable (local, get_local_cvalue (local), value, initializer);
 	}
 }
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 8442620..09deb15 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2006,179 +2006,21 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 	public override void visit_local_variable (LocalVariable local) {
 		check_type (local.variable_type);
 
-		if (local.initializer != null) {
-			local.initializer.emit (this);
-
-			visit_end_full_expression (local.initializer);
-		}
-
 		generate_type_declaration (local.variable_type, cfile);
 
-		if (!local.captured) {
-			if (local.variable_type is ArrayType) {
-				// create variables to store array dimensions
-				var array_type = (ArrayType) local.variable_type;
-
-				if (!array_type.fixed_length) {
-					for (int dim = 1; dim <= array_type.rank; dim++) {
-						var len_var = new LocalVariable (int_type.copy (), get_array_length_cname (get_variable_cname (local.name), dim));
-						emit_temp_var (len_var);
-					}
-
-					if (array_type.rank == 1) {
-						var size_var = new LocalVariable (int_type.copy (), get_array_size_cname (get_variable_cname (local.name)));
-						emit_temp_var (size_var);
-					}
-				}
-			} else if (local.variable_type is DelegateType) {
-				var deleg_type = (DelegateType) local.variable_type;
-				var d = deleg_type.delegate_symbol;
-				if (d.has_target) {
-					// create variable to store delegate target
-					var target_var = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (get_variable_cname (local.name)));
-					emit_temp_var (target_var);
-					if (deleg_type.value_owned) {
-						var target_destroy_notify_var = new LocalVariable (gdestroynotify_type, get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
-						emit_temp_var (target_destroy_notify_var);
-					}
-				}
-			}
-		}
-	
-		CCodeExpression rhs = null;
-		if (local.initializer != null && get_cvalue (local.initializer) != null) {
-			var target_value = get_variable_cvalue (local);
-
-			rhs = get_cvalue (local.initializer);
-
-			if (local.variable_type is ArrayType) {
-				var array_type = (ArrayType) local.variable_type;
-
-				if (array_type.fixed_length) {
-					rhs = null;
-				} else {
-					var temp_var = get_temp_variable (local.variable_type, true, local, false);
-					emit_temp_var (temp_var);
-					ccode.add_assignment (get_variable_cexpression (temp_var.name), rhs);
-
-					for (int dim = 1; dim <= array_type.rank; dim++) {
-						var lhs_array_len = get_array_length_cvalue (target_value, dim);
-						var rhs_array_len = get_array_length_cexpression (local.initializer, dim);
-						ccode.add_assignment (lhs_array_len, rhs_array_len);
-					}
-					if (array_type.rank == 1 && !local.captured) {
-						var lhs_array_size = get_array_size_cvalue (target_value);
-						var rhs_array_len = get_array_length_cvalue (target_value, 1);
-						ccode.add_assignment (lhs_array_size, rhs_array_len);
-					}
-
-					rhs = get_variable_cexpression (temp_var.name);
-				}
-			} else if (local.variable_type is DelegateType) {
-				var deleg_type = (DelegateType) local.variable_type;
-				var d = deleg_type.delegate_symbol;
-				if (d.has_target) {
-					var temp_var = get_temp_variable (local.variable_type, true, local, false);
-					emit_temp_var (temp_var);
-					ccode.add_assignment (get_variable_cexpression (temp_var.name), rhs);
-
-					var lhs_delegate_target = get_delegate_target_cvalue (target_value);
-					var lhs_delegate_target_destroy_notify = get_delegate_target_destroy_notify_cvalue (target_value);
-
-					CCodeExpression rhs_delegate_target_destroy_notify;
-					var rhs_delegate_target = get_delegate_target_cexpression (local.initializer, out rhs_delegate_target_destroy_notify);
-					ccode.add_assignment (lhs_delegate_target, rhs_delegate_target);
-
-					if (deleg_type.value_owned) {
-						ccode.add_assignment (lhs_delegate_target_destroy_notify, rhs_delegate_target_destroy_notify);
-					}
-
-					rhs = get_variable_cexpression (temp_var.name);
-				}
-			}
-		} else if (local.variable_type.is_reference_type_or_type_parameter ()) {
-			rhs = new CCodeConstant ("NULL");
-
-			if (local.variable_type is ArrayType) {
-				// initialize array length variables
-				var array_type = (ArrayType) local.variable_type;
-
-				if (array_type.fixed_length) {
-					rhs = null;
-				} else {
-					for (int dim = 1; dim <= array_type.rank; dim++) {
-						ccode.add_assignment (get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)), new CCodeConstant ("0"));
-					}
-				}
-			}
-		}
-
-		if (local.captured) {
-			if (local.initializer != null) {
-				if (has_simple_struct_initializer (local)) {
-					ccode.add_expression (rhs);
-				} else {
-					ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs);
-				}
-			}
-		} else if (current_method != null && current_method.coroutine) {
-			closure_struct.add_field (local.variable_type.get_cname (), get_variable_cname (local.name) + local.variable_type.get_cdeclarator_suffix ());
-
-			if (local.initializer != null) {
-				if (has_simple_struct_initializer (local)) {
-					ccode.add_expression (rhs);
-				} else {
-					ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_variable_cname (local.name)), rhs);
-				}
-			}
-		} else {
-			CCodeExpression post_rhs = null;
-			if (has_simple_struct_initializer (local)) {
-				post_rhs = rhs;
-				rhs = null;
-			}
-
-			var cvar = new CCodeVariableDeclarator (get_variable_cname (local.name), rhs, local.variable_type.get_cdeclarator_suffix ());
-			if (rhs != null) {
-				cvar.line = rhs.line;
-			}
-
-			// try to initialize uninitialized variables
-			// initialization not necessary for variables stored in closure
-			if (cvar.initializer == null) {
-				cvar.initializer = default_value_for_type (local.variable_type, true);
-				cvar.init0 = true;
-			}
-
-			ccode.add_declaration (local.variable_type.get_cname (), cvar);
-
-			if (cvar.initializer != null && !cvar.init0) {
-				cvar.initializer = null;
-				ccode.add_assignment (get_variable_cexpression (local.name), rhs);
-			}
-
-			if (post_rhs != null) {
-				ccode.add_expression (post_rhs);
-			}
+		if (local.initializer != null) {
+			local.no_init = true;
 		}
 
-		if (local.initializer != null && local.variable_type is ArrayType) {
-			var array_type = (ArrayType) local.variable_type;
+		emit_local (local);
 
-			if (array_type.fixed_length) {
-				cfile.add_include ("string.h");
+		if (local.initializer != null) {
+			local.initializer.emit (this);
 
-				// it is necessary to use memcpy for fixed-length (stack-allocated) arrays
-				// simple assignments do not work in C
-				var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
-				sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
-				var size = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("%d".printf (array_type.length)), sizeof_call);
+			visit_end_full_expression (local.initializer);
 
-				var ccopy = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
-				ccopy.add_argument (get_variable_cexpression (local.name));
-				ccopy.add_argument (get_cvalue (local.initializer));
-				ccopy.add_argument (size);
-				ccode.add_expression (ccopy);
+			if (!has_simple_struct_initializer (local)) {
+				store_local (local, local.initializer.target_value, true);
 			}
 		}
 
@@ -3098,20 +2940,53 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		
 		temp_ref_vars.clear ();
 	}
-	
+
 	public void emit_temp_var (LocalVariable local) {
-		var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
+		emit_local (local);
+	}
+
+	public void emit_local (LocalVariable local) {
+		var vardecl = new CCodeVariableDeclarator (get_variable_cname (local.name), null, local.variable_type.get_cdeclarator_suffix ());
 
 		var st = local.variable_type.data_type as Struct;
 		var array_type = local.variable_type as ArrayType;
 
+		if (!local.captured) {
+			if (array_type != null) {
+				// create variables to store array dimensions
+				if (!array_type.fixed_length) {
+					for (int dim = 1; dim <= array_type.rank; dim++) {
+						var len_var = new LocalVariable (int_type.copy (), get_array_length_cname (get_variable_cname (local.name), dim));
+						emit_local (len_var);
+					}
+
+					if (array_type.rank == 1) {
+						var size_var = new LocalVariable (int_type.copy (), get_array_size_cname (get_variable_cname (local.name)));
+						emit_local (size_var);
+					}
+				}
+			} else if (local.variable_type is DelegateType) {
+				var deleg_type = (DelegateType) local.variable_type;
+				var d = deleg_type.delegate_symbol;
+				if (d.has_target) {
+					// create variable to store delegate target
+					var target_var = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (get_variable_cname (local.name)));
+					emit_local (target_var);
+					if (deleg_type.value_owned) {
+						var target_destroy_notify_var = new LocalVariable (gdestroynotify_type, get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
+						emit_local (target_destroy_notify_var);
+					}
+				}
+			}
+		}
+
 		if (local.name.has_prefix ("*")) {
 			// do not dereference unintialized variable
 			// initialization is not needed for these special
 			// pointer temp variables
 			// used to avoid side-effects in assignments
 		} else if (local.no_init) {
-			// no initialization necessary for this temp var
+			// no initialization necessary for this var
 		} else if (!local.variable_type.nullable &&
 		           (st != null && !st.is_simple_type ()) ||
 		           (array_type != null && array_type.fixed_length)) {
@@ -3127,10 +3002,20 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		           local.variable_type is DelegateType) {
 			vardecl.initializer = new CCodeConstant ("NULL");
 			vardecl.init0 = true;
+
+			if (array_type != null) {
+				// initialize array length variables
+				for (int dim = 1; dim <= array_type.rank; dim++) {
+					ccode.add_assignment (get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)), new CCodeConstant ("0"));
+				}
+			}
+		} else {
+			vardecl.initializer = default_value_for_type (local.variable_type, true);
+			vardecl.init0 = true;
 		}
 
 		if (current_method != null && current_method.coroutine) {
-			closure_struct.add_field (local.variable_type.get_cname (), local.name);
+			closure_struct.add_field (local.variable_type.get_cname (), get_variable_cname (local.name));
 
 			// even though closure struct is zerod, we need to initialize temporary variables
 			// as they might be used multiple times when declared in a loop
@@ -4329,7 +4214,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		var local = expr.parent_node as LocalVariable;
 		if (local != null && has_simple_struct_initializer (local)) {
 			// no temporary variable necessary
-			set_cvalue (expr, creation_expr);
+			ccode.add_expression (creation_expr);
+			set_cvalue (expr, instance);
 			return;
 		} else if (instance != null) {
 			if (expr.type_reference.data_type is Struct) {
@@ -5169,22 +5055,16 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				ccode.add_assignment (get_variable_cexpression (decl.name), cexpr);
 				cexpr = get_variable_cexpression (decl.name);
 
+				var target_value = get_variable_cvalue (decl);
 				if (expression_type is ArrayType && expr != null) {
 					var array_type = (ArrayType) expression_type;
 					for (int dim = 1; dim <= array_type.rank; dim++) {
-						var len_decl = new LocalVariable (int_type.copy (), get_array_length_cname (decl.name, dim));
-						emit_temp_var (len_decl);
-						ccode.add_assignment (get_variable_cexpression (len_decl.name), get_array_length_cexpression (expr, dim));
+						ccode.add_assignment (get_array_length_cvalue (target_value, dim), get_array_length_cexpression (expr, dim));
 					}
 				} else if (expression_type is DelegateType && expr != null) {
-					var target_decl = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (decl.name));
-					emit_temp_var (target_decl);
-					var target_destroy_notify_decl = new LocalVariable (gdestroynotify_type, get_delegate_target_destroy_notify_cname (decl.name));
-					emit_temp_var (target_destroy_notify_decl);
 					CCodeExpression target_destroy_notify;
-					ccode.add_assignment (get_variable_cexpression (target_decl.name), get_delegate_target_cexpression (expr, out target_destroy_notify));
-					ccode.add_assignment (get_variable_cexpression (target_destroy_notify_decl.name), target_destroy_notify);
-
+					ccode.add_assignment (get_delegate_target_cvalue (target_value), get_delegate_target_cexpression (expr, out target_destroy_notify));
+					ccode.add_assignment (get_delegate_target_destroy_notify_cvalue (target_value), target_destroy_notify);
 				}
 			}
 		}
diff --git a/codegen/valadovaassignmentmodule.vala b/codegen/valadovaassignmentmodule.vala
index cf94b79..3aef397 100644
--- a/codegen/valadovaassignmentmodule.vala
+++ b/codegen/valadovaassignmentmodule.vala
@@ -132,7 +132,7 @@ public class Vala.DovaAssignmentModule : DovaMemberAccessModule {
 		}
 	}
 
-	void store_variable (Variable variable, TargetValue lvalue, TargetValue value) {
+	void store_variable (Variable variable, TargetValue lvalue, TargetValue value, bool initializer) {
 		if (requires_destroy (variable.variable_type)) {
 			/* unref old value */
 			ccode.add_expression (destroy_value (lvalue));
@@ -141,7 +141,7 @@ public class Vala.DovaAssignmentModule : DovaMemberAccessModule {
 		ccode.add_assignment (get_cvalue_ (lvalue), get_cvalue_ (value));
 	}
 
-	public override void store_local (LocalVariable local, TargetValue value) {
-		store_variable (local, get_local_cvalue (local), value);
+	public override void store_local (LocalVariable local, TargetValue value, bool initializer) {
+		store_variable (local, get_local_cvalue (local), value, initializer);
 	}
 }
diff --git a/vala/valacodegenerator.vala b/vala/valacodegenerator.vala
index 9c33fcd..65624f4 100644
--- a/vala/valacodegenerator.vala
+++ b/vala/valacodegenerator.vala
@@ -36,5 +36,5 @@ public abstract class Vala.CodeGenerator : CodeVisitor {
 
 	public abstract TargetValue load_local (LocalVariable local);
 
-	public abstract void store_local (LocalVariable local, TargetValue value);
+	public abstract void store_local (LocalVariable local, TargetValue value, bool initializer);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]