[vala/wip/effectfree: 9/12] codegen: Add create_temp_value



commit 8a2623dfe760e05c84319728be9b0b17b723176c
Author: Luca Bruno <lucabru src gnome org>
Date:   Sat Jun 11 10:16:32 2011 +0200

    codegen: Add create_temp_value

 codegen/valaccodebasemodule.vala |   69 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 69 insertions(+), 0 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 62a6d45..8b7e51c 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2106,6 +2106,75 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		local.active = true;
 	}
 
+	private void emit_temp_part (DataType type, string name, bool init) {
+		if (is_in_coroutine ()) {
+			closure_struct.add_field (type.get_cname (), 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
+
+			if (init) {
+				var initializer = default_value_for_type (type, false);
+				if (initializer == null) {
+					cfile.add_include ("string.h");
+					var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+					memset_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (name)));
+					memset_call.add_argument (new CCodeConstant ("0"));
+					memset_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (type.get_cname ())));
+					ccode.add_expression (memset_call);
+				} else {
+					ccode.add_assignment (get_variable_cexpression (name), initializer);
+				}
+			}
+		} else {
+			var cvar = new CCodeVariableDeclarator (name, null, type.get_cdeclarator_suffix ());
+			if (init) {
+				cvar.initializer = default_value_for_type (type, true);
+				cvar.init0 = true;
+			}
+			ccode.add_declaration (type.get_cname (), cvar);
+		}
+	}
+
+	/**
+	 * Create a temporary variable and return unowned or owned rvalue access to it,
+	 * depending on the ownership of the given type.
+	 * If initializer is null, the variable is initialized with default values.
+	 */
+	public TargetValue create_temp_value (DataType type, TargetValue? initializer, CodeNode node_reference, bool? value_owned = null) {
+		var local = new LocalVariable (type.copy (), "_tmp%d_".printf (next_temp_var_id++), null, node_reference.source_reference);
+		if (value_owned != null) {
+			local.variable_type.value_owned = value_owned;
+		}
+
+		var array_type = local.variable_type as ArrayType;
+		var deleg_type = local.variable_type as DelegateType;
+		emit_temp_part (local.variable_type, local.name, initializer == null);
+		if (array_type != null) {
+			for (int dim = 1; dim <= array_type.rank; dim++) {
+				emit_temp_part (int_type, get_array_length_cname (local.name, dim), initializer == null);
+			}
+		} else if (deleg_type != null) {
+			if (deleg_type.delegate_symbol.has_target) {
+				emit_temp_part (new PointerType (new VoidType ()), get_delegate_target_cname (local.name), initializer == null);
+				if (deleg_type.value_owned) {
+					emit_temp_part (gdestroynotify_type, get_delegate_target_destroy_notify_cname (local.name), initializer == null);
+				}
+			}
+		}
+
+		var lvalue = get_local_cvalue (local);
+		set_array_size_cvalue (lvalue, null);
+		if (initializer != null) {
+			store_value (lvalue, initializer);
+		}
+		var value = load_local (local);
+		if (deleg_type != null && deleg_type.value_owned) {
+			((GLibValue) value).delegate_target_destroy_notify_cvalue = get_delegate_target_destroy_notify_cvalue (lvalue);
+		}
+		return value;
+	}
+
 	public override void visit_initializer_list (InitializerList list) {
 		if (list.target_type.data_type is Struct) {
 			/* initializer is used as struct initializer */



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