[vala/emit-let: 4/10] codegen: Introduce emit_local and use store_local for visit_local_variable.
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/emit-let: 4/10] codegen: Introduce emit_local and use store_local for visit_local_variable.
- Date: Wed, 19 Jan 2011 12:38:58 +0000 (UTC)
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]