[vala] codegen: Add CodeGenerator.load_local



commit aba026131a1185bad37465e58d9f713dd9360d42
Author: Jürg Billeter <j bitron ch>
Date:   Thu Oct 21 13:17:09 2010 +0200

    codegen: Add CodeGenerator.load_local

 codegen/valaccodebasemodule.vala         |    2 +-
 codegen/valaccodecontrolflowmodule.vala  |    2 +-
 codegen/valaccodememberaccessmodule.vala |  123 +++++++++++++++++------------
 codegen/valaccodemethodmodule.vala       |    2 +-
 codegen/valaccodestructmodule.vala       |    2 +-
 codegen/valadovabasemodule.vala          |    2 +-
 codegen/valadovacontrolflowmodule.vala   |    2 +-
 codegen/valadovamemberaccessmodule.vala  |   36 ++++++---
 codegen/valadovamethodmodule.vala        |    2 +-
 codegen/valadovastructmodule.vala        |    2 +-
 vala/valacodegenerator.vala              |    2 +
 11 files changed, 108 insertions(+), 69 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 427def8..7bbcc92 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -26,7 +26,7 @@
 /**
  * Code visitor generating C Code.
  */
-public class Vala.CCodeBaseModule : CodeGenerator {
+public abstract class Vala.CCodeBaseModule : CodeGenerator {
 	public class EmitContext {
 		public Symbol? current_symbol;
 		public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala
index c940088..254250b 100644
--- a/codegen/valaccodecontrolflowmodule.vala
+++ b/codegen/valaccodecontrolflowmodule.vala
@@ -24,7 +24,7 @@
 
 using GLib;
 
-public class Vala.CCodeControlFlowModule : CCodeMethodModule {
+public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
 	public override void visit_if_statement (IfStatement stmt) {
 		ccode.open_if (get_cvalue (stmt.condition));
 
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index af62122..d0b4eb3 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -471,59 +471,21 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 			}
 		} else if (expr.symbol_reference is LocalVariable) {
 			var local = (LocalVariable) expr.symbol_reference;
-			if (local.is_result) {
-				// used in postconditions
-				// structs are returned as out parameter
-				if (local.variable_type != null && local.variable_type.is_real_non_null_struct_type ()) {
-					set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result")));
-				} else {
-					set_cvalue (expr, new CCodeIdentifier ("result"));
-				}
-			} else if (local.captured) {
-				// captured variables are stored on the heap
-				var block = (Block) local.parent_symbol;
-				set_cvalue (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name)));
-				if (array_type != null) {
-					for (int dim = 1; dim <= array_type.rank; dim++) {
-						append_array_size (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_variable_cname (local.name), dim)));
-					}
-				} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
-					set_delegate_target (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (local.name))));
-					set_delegate_target_destroy_notify (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name))));
-				}
-			} else {
-				set_cvalue (expr, get_variable_cexpression (local.name));
-				if (array_type != null) {
-					for (int dim = 1; dim <= array_type.rank; dim++) {
-						append_array_size (expr, get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)));
-					}
-				} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
-					if (current_method != null && current_method.coroutine) {
-						set_delegate_target (expr, new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (local.name))));
-						set_delegate_target_destroy_notify (expr, new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name))));
-					} else {
-						set_delegate_target (expr, new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (local.name))));
-						if (expr.value_type.value_owned) {
-							set_delegate_target_destroy_notify (expr, new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (local.name))));
-						} else {
-							set_delegate_target_destroy_notify (expr, new CCodeConstant ("NULL"));
-						}
-					}
-				}
+			expr.target_value = load_local (local);
 
-				if (expr.parent_node is ReturnStatement &&
-				    current_return_type.value_owned &&
-				    local.variable_type.value_owned &&
-				    !variable_accessible_in_finally (local)) {
-					/* return expression is local variable taking ownership and
-					 * current method is transferring ownership */
+			if (expr.parent_node is ReturnStatement &&
+			    current_return_type.value_owned &&
+			    local.variable_type.value_owned &&
+			    !local.captured &&
+			    !variable_accessible_in_finally (local)) {
+				/* return expression is local variable taking ownership and
+				 * current method is transferring ownership */
 
-					// don't ref expression
-					expr.value_type.value_owned = true;
+				// don't ref expression
+				expr.value_type.value_owned = true;
 
-					// don't unref variable
-					local.active = false;
-				}
+				// don't unref variable
+				local.active = false;
 			}
 		} else if (expr.symbol_reference is FormalParameter) {
 			var p = (FormalParameter) expr.symbol_reference;
@@ -627,5 +589,64 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 			}
 		}
 	}
-}
 
+	public TargetValue get_local_cvalue (LocalVariable local) {
+		var result = new GLibValue (local.variable_type);
+
+		var array_type = local.variable_type as ArrayType;
+		var delegate_type = local.variable_type as DelegateType;
+
+		if (local.is_result) {
+			// used in postconditions
+			// structs are returned as out parameter
+			if (local.variable_type != null && local.variable_type.is_real_non_null_struct_type ()) {
+				result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
+			} else {
+				result.cvalue = new CCodeIdentifier ("result");
+			}
+		} else if (local.captured) {
+			// captured variables are stored on the heap
+			var block = (Block) local.parent_symbol;
+			result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name));
+			if (array_type != null) {
+				for (int dim = 1; dim <= array_type.rank; dim++) {
+					result.append_array_length_cvalue (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_variable_cname (local.name), dim)));
+				}
+			} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
+				result.delegate_target_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (local.name)));
+				result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
+			}
+		} else {
+			result.cvalue = get_variable_cexpression (local.name);
+			if (array_type != null) {
+				for (int dim = 1; dim <= array_type.rank; dim++) {
+					result.append_array_length_cvalue (get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)));
+				}
+			} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
+				if (current_method != null && current_method.coroutine) {
+					result.delegate_target_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (local.name)));
+					result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
+				} else {
+					result.delegate_target_cvalue = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (local.name)));
+					if (local.variable_type.value_owned) {
+						result.delegate_target_destroy_notify_cvalue = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
+					}
+				}
+			}
+		}
+
+		return result;
+	}
+
+	TargetValue load_variable (Variable variable, TargetValue value) {
+		return value;
+	}
+
+	public override TargetValue load_local (LocalVariable local) {
+		var result = (GLibValue) get_local_cvalue (local);
+		if (local.variable_type is DelegateType && result.delegate_target_destroy_notify_cvalue == null) {
+			result.delegate_target_destroy_notify_cvalue = new CCodeConstant ("NULL");
+		}
+		return load_variable (local, result);
+	}
+}
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index a457f89..202e915 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -26,7 +26,7 @@ using GLib;
 /**
  * The link between a method and generated code.
  */
-public class Vala.CCodeMethodModule : CCodeStructModule {
+public abstract class Vala.CCodeMethodModule : CCodeStructModule {
 	public override bool method_has_wrapper (Method method) {
 		return (method.get_attribute ("NoWrapper") == null);
 	}
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index 07f7525..bd6de01 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -24,7 +24,7 @@
 
 using GLib;
 
-public class Vala.CCodeStructModule : CCodeBaseModule {
+public abstract class Vala.CCodeStructModule : CCodeBaseModule {
 	public override void generate_struct_declaration (Struct st, CCodeFile decl_space) {
 		if (add_symbol_declaration (decl_space, st, st.get_cname ())) {
 			return;
diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala
index ae7bea0..63ebb6d 100644
--- a/codegen/valadovabasemodule.vala
+++ b/codegen/valadovabasemodule.vala
@@ -25,7 +25,7 @@
 /**
  * Code visitor generating C Code.
  */
-public class Vala.DovaBaseModule : CodeGenerator {
+public abstract class Vala.DovaBaseModule : CodeGenerator {
 	public class EmitContext {
 		public Symbol? current_symbol;
 		public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
diff --git a/codegen/valadovacontrolflowmodule.vala b/codegen/valadovacontrolflowmodule.vala
index ac17c14..115ac7d 100644
--- a/codegen/valadovacontrolflowmodule.vala
+++ b/codegen/valadovacontrolflowmodule.vala
@@ -20,7 +20,7 @@
  * 	Jürg Billeter <j bitron ch>
  */
 
-public class Vala.DovaControlFlowModule : DovaMethodModule {
+public abstract class Vala.DovaControlFlowModule : DovaMethodModule {
 	public override void visit_if_statement (IfStatement stmt) {
 		ccode.open_if (get_cvalue (stmt.condition));
 
diff --git a/codegen/valadovamemberaccessmodule.vala b/codegen/valadovamemberaccessmodule.vala
index 5e6f0d9..758990b 100644
--- a/codegen/valadovamemberaccessmodule.vala
+++ b/codegen/valadovamemberaccessmodule.vala
@@ -189,16 +189,7 @@ public class Vala.DovaMemberAccessModule : DovaControlFlowModule {
 			set_cvalue (expr, ccall);
 		} else if (expr.symbol_reference is LocalVariable) {
 			var local = (LocalVariable) expr.symbol_reference;
-			if (local.is_result) {
-				// used in postconditions
-				set_cvalue (expr, new CCodeIdentifier ("result"));
-			} else if (local.captured) {
-				// captured variables are stored on the heap
-				var block = (Block) local.parent_symbol;
-				set_cvalue (expr, new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name)));
-			} else {
-				set_cvalue (expr, get_variable_cexpression (local.name));
-			}
+			expr.target_value = load_local (local);
 		} else if (expr.symbol_reference is FormalParameter) {
 			var p = (FormalParameter) expr.symbol_reference;
 			if (p.name == "this") {
@@ -252,5 +243,30 @@ public class Vala.DovaMemberAccessModule : DovaControlFlowModule {
 			}
 		}
 	}
+
+	public TargetValue get_local_cvalue (LocalVariable local) {
+		var result = new GLibValue (local.variable_type);
+
+		if (local.is_result) {
+			// used in postconditions
+			result.cvalue = new CCodeIdentifier ("result");
+		} else if (local.captured) {
+			// captured variables are stored on the heap
+			var block = (Block) local.parent_symbol;
+			result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name));
+		} else {
+			result.cvalue = get_variable_cexpression (local.name);
+		}
+
+		return result;
+	}
+
+	TargetValue load_variable (Variable variable, TargetValue value) {
+		return value;
+	}
+
+	public override TargetValue load_local (LocalVariable local) {
+		return load_variable (local, get_local_cvalue (local));
+	}
 }
 
diff --git a/codegen/valadovamethodmodule.vala b/codegen/valadovamethodmodule.vala
index 3450941..b195fc6 100644
--- a/codegen/valadovamethodmodule.vala
+++ b/codegen/valadovamethodmodule.vala
@@ -23,7 +23,7 @@
 /**
  * The link between a method and generated code.
  */
-public class Vala.DovaMethodModule : DovaStructModule {
+public abstract class Vala.DovaMethodModule : DovaStructModule {
 	public override bool method_has_wrapper (Method method) {
 		return (method.get_attribute ("NoWrapper") == null);
 	}
diff --git a/codegen/valadovastructmodule.vala b/codegen/valadovastructmodule.vala
index 2c6cdf2..94d7ef4 100644
--- a/codegen/valadovastructmodule.vala
+++ b/codegen/valadovastructmodule.vala
@@ -22,7 +22,7 @@
 
 using GLib;
 
-public class Vala.DovaStructModule : DovaBaseModule {
+public abstract class Vala.DovaStructModule : DovaBaseModule {
 	public override void generate_struct_declaration (Struct st, CCodeFile decl_space) {
 		if (add_symbol_declaration (decl_space, st, st.get_cname ())) {
 			return;
diff --git a/vala/valacodegenerator.vala b/vala/valacodegenerator.vala
index 08713bc..b1b8f92 100644
--- a/vala/valacodegenerator.vala
+++ b/vala/valacodegenerator.vala
@@ -33,4 +33,6 @@ public abstract class Vala.CodeGenerator : CodeVisitor {
 	}
 
 	public abstract LocalVariable create_local (DataType type);
+
+	public abstract TargetValue load_local (LocalVariable local);
 }



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