[vala/wip/effectfree: 14/33] codegen: Make transform_value be effect-free



commit 510f0b1ff1b47c4d3592a72a6e13c3248f4203d9
Author: Luca Bruno <lucabru src gnome org>
Date:   Fri Jun 17 14:51:01 2011 +0200

    codegen: Make transform_value be effect-free

 codegen/valaccodebasemodule.vala |   35 +++++++++++++++++------------------
 1 files changed, 17 insertions(+), 18 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 730c4ce..3c390d2 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -5091,7 +5091,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		var type = value.value_type;
 		var result = ((GLibValue) value).copy ();
 		result.value_type = target_type != null ? target_type : type;
-		result.cvalue = get_cvalue_ (value);
+		var requires_temp_value = false;
 
 		if (type.value_owned
 		    && type.floating_reference) {
@@ -5105,6 +5105,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 				csink.add_argument (result.cvalue);
 				
 				result.cvalue = csink;
+				requires_temp_value = true;
 			} else {
 				Report.error (null, "type `%s' does not support floating references".printf (type.data_type.name));
 			}
@@ -5157,6 +5158,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 					ccode.add_assignment (get_variable_cexpression (target_destroy_notify_decl.name), get_delegate_target_destroy_notify_cvalue (value));
 
 				}
+				requires_temp_value = false;
 			}
 		}
 
@@ -5210,7 +5212,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 			ccode.add_expression (ccall);
 
-			return get_local_cvalue (decl);
+			result = (GLibValue) get_local_cvalue (decl);
+			requires_temp_value = false;
 		} else if (gvariant_boxing) {
 			// implicit conversion to GVariant
 			string variant_func = "_variant_new%d".printf (++next_variant_function_id);
@@ -5245,7 +5248,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 			cfile.add_function (cfunc);
 
 			result.cvalue = ccall;
-			return result;
+			requires_temp_value = true;
 		} else if (boxing) {
 			// value needs to be boxed
 
@@ -5261,6 +5264,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
 				ccode.add_assignment (get_variable_cexpression (decl.name), result.cvalue);
 				result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (decl.name));
+				requires_temp_value = false;
 			}
 		} else if (unboxing) {
 			// unbox value
@@ -5270,23 +5274,18 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 			result.cvalue = get_implicit_cast_expression (result.cvalue, type, target_type, node);
 		}
 
-		if (target_type.value_owned && (!type.value_owned || boxing || unboxing)) {
+		if (requires_temp_value && !(target_type is ArrayType && ((ArrayType) target_type).inline_allocated)) {
+			result = (GLibValue) store_temp_value (result, node);
+		}
+
+		if (!gvalue_boxing && !gvariant_boxing && target_type.value_owned && (!type.value_owned || boxing || unboxing) && requires_copy (target_type) && !(type is NullType)) {
 			// need to copy value
-			if (requires_copy (target_type) && !(type is NullType)) {
-				var copy = (GLibValue) copy_value (result, node);
-				if (target_type.data_type is Interface && copy == null) {
-					Report.error (node.source_reference, "missing class prerequisite for interface `%s', add GLib.Object to interface declaration if unsure".printf (target_type.data_type.get_full_name ()));
-					return result;
-				}
-				result = copy;
-				// drop this assignment when target values are guaranteed to be effect-free
-				if (!(target_type is ArrayType && ((ArrayType) target_type).fixed_length)) {
-					var decl = get_temp_variable (target_type, true, node, false);
-					emit_temp_var (decl);
-					ccode.add_assignment (get_variable_cexpression (decl.name), get_cvalue_ (result));
-					result.cvalue = get_variable_cexpression (decl.name);
-				}
+			var copy = (GLibValue) copy_value (result, node);
+			if (target_type.data_type is Interface && copy == null) {
+				Report.error (node.source_reference, "missing class prerequisite for interface `%s', add GLib.Object to interface declaration if unsure".printf (target_type.data_type.get_full_name ()));
+				return result;
 			}
+			result = copy;
 		}
 
 		return result;



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