]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Add CodeGenerator.load_local
authorJürg Billeter <j@bitron.ch>
Thu, 21 Oct 2010 11:17:09 +0000 (13:17 +0200)
committerJürg Billeter <j@bitron.ch>
Thu, 28 Oct 2010 09:43:44 +0000 (11:43 +0200)
codegen/valaccodebasemodule.vala
codegen/valaccodecontrolflowmodule.vala
codegen/valaccodememberaccessmodule.vala
codegen/valaccodemethodmodule.vala
codegen/valaccodestructmodule.vala
codegen/valadovabasemodule.vala
codegen/valadovacontrolflowmodule.vala
codegen/valadovamemberaccessmodule.vala
codegen/valadovamethodmodule.vala
codegen/valadovastructmodule.vala
vala/valacodegenerator.vala

index 427def83139481394fc854807a74b4ce44a2b88a..7bbcc929edaee9fd81e991303c6eff8b89629c1c 100644 (file)
@@ -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> ();
index c94008832fa1517f1e52e8f016b62752aece3ff6..254250b99ac9ba57631c380f00d2048a3f92c996 100644 (file)
@@ -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));
 
index af621227b2df04012a7b9fa4a39cfb8b0edc2e2d..d0b4eb38783f31e959ff78109cd2ad7c968bae37 100644 (file)
@@ -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);
+       }
+}
index a457f89adbebe07d23dad57db02944d6971fdcf0..202e9156b7f228e148f9538a3233aa0f567827b4 100644 (file)
@@ -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);
        }
index 07f7525528a33eec752f85bf60c8b22ea72a309a..bd6de018734deeb431149b6cedf6513cf90c4897 100644 (file)
@@ -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;
index ae7bea0b122c05beb4e2cf80db6583c68b268c22..63ebb6d14412d1c6d071c5e3041ba9add2e46e58 100644 (file)
@@ -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> ();
index ac17c14dd3469c1cdd96dfbec764be0004f7952a..115ac7db71c909974db8c2265ec165489183a235 100644 (file)
@@ -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));
 
index 5e6f0d9b29133bcc77d0f855b2e162d034a85bbc..758990b5f1e8a3eb6b291e061a63c68dd48a2492 100644 (file)
@@ -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));
+       }
 }
 
index 34509418b7cbf37902beb964e1f4b508f15ac9f7..b195fc6892be646cac01711108011e2e771437b2 100644 (file)
@@ -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);
        }
index 2c6cdf2c7e2bcfd92110adefcf1af5126f074af3..94d7ef49cdd06f69830061b2b0588adb9d65da9d 100644 (file)
@@ -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;
index 08713bc24d9537e8845a031260803973c665535b..b1b8f92cdf54fe5a7b484e112df1bc25834a3a56 100644 (file)
@@ -33,4 +33,6 @@ public abstract class Vala.CodeGenerator : CodeVisitor {
        }
 
        public abstract LocalVariable create_local (DataType type);
+
+       public abstract TargetValue load_local (LocalVariable local);
 }