[vala] codegen: Avoid name clashes in the closure struct
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] codegen: Avoid name clashes in the closure struct
- Date: Sun, 2 Oct 2011 11:45:31 +0000 (UTC)
commit 335636be07c27950791179dc77354d2916c9468a
Author: Luca Bruno <lucabru src gnome org>
Date: Mon Apr 11 18:08:23 2011 +0200
codegen: Avoid name clashes in the closure struct
Fixes bug 596861.
codegen/valaccodebasemodule.vala | 51 +++++++++++++++++++++++-------
codegen/valaccodecontrolflowmodule.vala | 32 +++++++++---------
codegen/valaccodememberaccessmodule.vala | 24 +++++++-------
codegen/valagasyncmodule.vala | 1 -
codegen/valagerrormodule.vala | 2 +-
tests/Makefile.am | 1 +
tests/asynchronous/bug596861.vala | 19 +++++++++++
7 files changed, 88 insertions(+), 42 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index ee23a6d..29feb48 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -39,6 +39,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
public bool current_method_inner_error;
public bool current_method_return;
public Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
+ public Map<string,int> closure_variable_count_map = new HashMap<string,int> (str_hash, str_equal);
+ public Map<LocalVariable,int> closure_variable_clash_map = new HashMap<LocalVariable,int> ();
public EmitContext (Symbol? symbol = null) {
current_symbol = symbol;
@@ -1785,18 +1787,18 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
if (local.captured) {
generate_type_declaration (local.variable_type, cfile);
- data.add_field (get_ccode_name (local.variable_type), get_variable_cname (local.name) + get_ccode_declarator_suffix (local.variable_type));
+ data.add_field (get_ccode_name (local.variable_type), get_local_cname (local) + get_ccode_declarator_suffix (local.variable_type));
if (local.variable_type is ArrayType) {
var array_type = (ArrayType) local.variable_type;
for (int dim = 1; dim <= array_type.rank; dim++) {
- data.add_field ("gint", get_array_length_cname (get_variable_cname (local.name), dim));
+ data.add_field ("gint", get_array_length_cname (get_local_cname (local), dim));
}
- data.add_field ("gint", get_array_size_cname (get_variable_cname (local.name)));
+ data.add_field ("gint", get_array_size_cname (get_local_cname (local)));
} else if (local.variable_type is DelegateType) {
- data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (local.name)));
+ data.add_field ("gpointer", get_delegate_target_cname (get_local_cname (local)));
if (local.variable_type.value_owned) {
- data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
+ data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_local_cname (local)));
}
}
}
@@ -2042,6 +2044,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
stmt.declaration.accept (this);
}
+ public CCodeExpression get_local_cexpression (LocalVariable local) {
+ if (is_in_coroutine ()) {
+ return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_local_cname (local));
+ } else {
+ return new CCodeIdentifier (get_local_cname (local));
+ }
+ }
+
public CCodeExpression get_variable_cexpression (string name) {
if (is_in_coroutine ()) {
return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), get_variable_cname (name));
@@ -2050,6 +2060,17 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
}
+ public string get_local_cname (LocalVariable local) {
+ var cname = get_variable_cname (local.name);
+ if (is_in_coroutine ()) {
+ var clash_index = emit_context.closure_variable_clash_map.get (local);
+ if (clash_index > 0) {
+ cname = "_vala%d_%s".printf (clash_index, cname);
+ }
+ }
+ return cname;
+ }
+
public string get_variable_cname (string name) {
if (name[0] == '.') {
if (name == ".result") {
@@ -2104,10 +2125,16 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
if (!local.captured) {
- if (current_method != null && current_method.coroutine) {
- closure_struct.add_field (get_ccode_name (local.variable_type), get_variable_cname (local.name) + get_ccode_declarator_suffix (local.variable_type));
+ if (is_in_coroutine ()) {
+ var count = emit_context.closure_variable_count_map.get (local.name);
+ if (count > 0) {
+ emit_context.closure_variable_clash_map.set (local, count);
+ }
+ emit_context.closure_variable_count_map.set (local.name, count + 1);
+
+ closure_struct.add_field (get_ccode_name (local.variable_type), get_local_cname (local) + get_ccode_declarator_suffix (local.variable_type));
} else {
- var cvar = new CCodeVariableDeclarator (get_variable_cname (local.name), null, get_ccode_declarator_suffix (local.variable_type));
+ var cvar = new CCodeVariableDeclarator (get_local_cname (local), null, get_ccode_declarator_suffix (local.variable_type));
// try to initialize uninitialized variables
// initialization not necessary for variables stored in closure
@@ -2125,13 +2152,13 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
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));
+ var len_var = new LocalVariable (int_type.copy (), get_array_length_cname (get_local_cname (local), dim));
len_var.no_init = local.initializer != null;
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)));
+ var size_var = new LocalVariable (int_type.copy (), get_array_size_cname (get_local_cname (local)));
size_var.no_init = local.initializer != null;
emit_temp_var (size_var);
}
@@ -2141,11 +2168,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
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)));
+ var target_var = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (get_local_cname (local)));
target_var.no_init = local.initializer != null;
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)));
+ var target_destroy_notify_var = new LocalVariable (gdestroynotify_type, get_delegate_target_destroy_notify_cname (get_local_cname (local)));
target_destroy_notify_var.no_init = local.initializer != null;
emit_temp_var (target_destroy_notify_var);
}
diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala
index faec8f4..5a4c297 100644
--- a/codegen/valaccodecontrolflowmodule.vala
+++ b/codegen/valaccodecontrolflowmodule.vala
@@ -232,7 +232,7 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
}
visit_local_variable (collection_backup);
- ccode.add_assignment (get_variable_cexpression (collection_backup.name), get_cvalue (stmt.collection));
+ ccode.add_assignment (get_variable_cexpression (get_local_cname (collection_backup)), get_cvalue (stmt.collection));
if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
// exception handling
@@ -245,11 +245,11 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
var array_len = get_array_length_cexpression (stmt.collection);
// store array length for use by _vala_array_free
- ccode.add_assignment (get_variable_cexpression (get_array_length_cname (collection_backup.name, 1)), array_len);
+ ccode.add_assignment (get_variable_cexpression (get_array_length_cname (get_local_cname (collection_backup), 1)), array_len);
var iterator_variable = new LocalVariable (int_type.copy (), stmt.variable_name + "_it");
- emit_temp_var (iterator_variable);
- var it_name = get_variable_cname (iterator_variable.name);
+ visit_local_variable (iterator_variable);
+ var it_name = get_local_cname (iterator_variable);
var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (it_name), array_len);
@@ -257,20 +257,20 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
ccond,
new CCodeAssignment (get_variable_cexpression (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (it_name), new CCodeConstant ("1"))));
- CCodeExpression element_expr = new CCodeElementAccess (get_variable_cexpression (collection_backup.name), get_variable_cexpression (it_name));
+ CCodeExpression element_expr = new CCodeElementAccess (get_variable_cexpression (get_local_cname (collection_backup)), get_variable_cexpression (it_name));
var element_type = array_type.element_type.copy ();
element_type.value_owned = false;
element_expr = get_cvalue_ (transform_value (new GLibValue (element_type, element_expr, true), stmt.type_reference, stmt));
visit_local_variable (stmt.element_variable);
- ccode.add_assignment (get_variable_cexpression (stmt.variable_name), element_expr);
+ ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
// set array length for stacked arrays
if (stmt.type_reference is ArrayType) {
var inner_array_type = (ArrayType) stmt.type_reference;
for (int dim = 1; dim <= inner_array_type.rank; dim++) {
- ccode.add_assignment (get_variable_cexpression (get_array_length_cname (stmt.variable_name, dim)), new CCodeConstant ("-1"));
+ ccode.add_assignment (get_variable_cexpression (get_array_length_cname (get_local_cname (stmt.element_variable), dim)), new CCodeConstant ("-1"));
}
}
@@ -281,12 +281,12 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
// iterating over a GList or GSList
var iterator_variable = new LocalVariable (collection_type.copy (), stmt.variable_name + "_it");
- emit_temp_var (iterator_variable);
- var it_name = get_variable_cname (iterator_variable.name);
+ visit_local_variable (iterator_variable);
+ var it_name = get_local_cname (iterator_variable);
var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (it_name), new CCodeConstant ("NULL"));
- ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), get_variable_cexpression (collection_backup.name)),
+ ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), get_variable_cexpression (get_local_cname (collection_backup))),
ccond,
new CCodeAssignment (get_variable_cexpression (it_name), new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "next")));
@@ -304,7 +304,7 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
element_expr = get_cvalue_ (transform_value (new GLibValue (element_data_type, element_expr), stmt.type_reference, stmt));
visit_local_variable (stmt.element_variable);
- ccode.add_assignment (get_variable_cexpression (stmt.variable_name), element_expr);
+ ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
stmt.body.emit (this);
@@ -313,17 +313,17 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
// iterating over a GValueArray
var iterator_variable = new LocalVariable (uint_type.copy (), "%s_index".printf (stmt.variable_name));
- emit_temp_var (iterator_variable);
- var arr_index = get_variable_cname (iterator_variable.name);
+ visit_local_variable (iterator_variable);
+ var arr_index = get_variable_cname (get_local_cname (iterator_variable));
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (collection_backup.name), "n_values"));
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (get_local_cname (collection_backup)), "n_values"));
ccode.open_for (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")),
ccond,
new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_get_nth"));
- get_item.add_argument (get_variable_cexpression (collection_backup.name));
+ get_item.add_argument (get_variable_cexpression (get_local_cname (collection_backup)));
get_item.add_argument (get_variable_cexpression (arr_index));
CCodeExpression element_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_item);
@@ -333,7 +333,7 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
}
visit_local_variable (stmt.element_variable);
- ccode.add_assignment (get_variable_cexpression (stmt.variable_name), element_expr);
+ ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
stmt.body.emit (this);
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index c4f75aa..818773f 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -336,39 +336,39 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
} 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));
+ result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_local_cname (local));
if (array_type != null && !array_type.fixed_length) {
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)));
+ result.append_array_length_cvalue (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_local_cname (local), dim)));
}
if (array_type.rank == 1) {
- result.array_size_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_size_cname (get_variable_cname (local.name)));
+ result.array_size_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_size_cname (get_local_cname (local)));
}
} 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_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_local_cname (local)));
if (delegate_type.value_owned) {
- 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)));
+ 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_local_cname (local)));
}
}
} else {
- result.cvalue = get_variable_cexpression (local.name);
+ result.cvalue = get_local_cexpression (local);
if (array_type != null && !array_type.fixed_length) {
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)));
+ result.append_array_length_cvalue (get_variable_cexpression (get_array_length_cname (get_local_cname (local), dim)));
}
if (array_type.rank == 1) {
- result.array_size_cvalue = get_variable_cexpression (get_array_size_cname (get_variable_cname (local.name)));
+ result.array_size_cvalue = get_variable_cexpression (get_array_size_cname (get_local_cname (local)));
}
} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
if (is_in_coroutine ()) {
- result.delegate_target_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), get_delegate_target_cname (get_variable_cname (local.name)));
+ result.delegate_target_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), get_delegate_target_cname (get_local_cname (local)));
if (local.variable_type.value_owned) {
- result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), get_delegate_target_destroy_notify_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_local_cname (local)));
}
} else {
- result.delegate_target_cvalue = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (local.name)));
+ result.delegate_target_cvalue = new CCodeIdentifier (get_delegate_target_cname (get_local_cname (local)));
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)));
+ result.delegate_target_destroy_notify_cvalue = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_local_cname (local)));
}
}
}
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index a7c4af1..64ec2b5 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -386,7 +386,6 @@ public class Vala.GAsyncModule : GSignalModule {
}
}
-
void generate_finish_function (Method m) {
push_context (new EmitContext ());
diff --git a/codegen/valagerrormodule.vala b/codegen/valagerrormodule.vala
index 10a080a..23d11a3 100644
--- a/codegen/valagerrormodule.vala
+++ b/codegen/valagerrormodule.vala
@@ -346,7 +346,7 @@ public class Vala.GErrorModule : CCodeDelegateModule {
if (clause.error_variable != null) {
visit_local_variable (clause.error_variable);
- ccode.add_assignment (get_variable_cexpression (clause.error_variable.name), get_variable_cexpression ("_inner_error_"));
+ ccode.add_assignment (get_variable_cexpression (get_local_cname (clause.error_variable)), get_variable_cexpression ("_inner_error_"));
} else {
// error object is not used within catch statement, clear it
var cclear = new CCodeFunctionCall (new CCodeIdentifier ("g_clear_error"));
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 303be72..1ce7421 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -123,6 +123,7 @@ TESTS = \
asynchronous/bug595735.vala \
asynchronous/bug595755.vala \
asynchronous/bug596177.vala \
+ asynchronous/bug596861.vala \
asynchronous/bug597294.vala \
asynchronous/bug598677.vala \
asynchronous/bug598697.vala \
diff --git a/tests/asynchronous/bug596861.vala b/tests/asynchronous/bug596861.vala
new file mode 100644
index 0000000..f73ccfa
--- /dev/null
+++ b/tests/asynchronous/bug596861.vala
@@ -0,0 +1,19 @@
+async int foo () throws Error {
+ try {
+ yield foo ();
+ } catch (Error e) {
+ try {
+ yield foo ();
+ } catch (Error e) {
+ return 0;
+ }
+ }
+ foreach (var e in new int[]{1,2,3}) {
+ }
+ foreach (var e in new int[]{1,2,3}) {
+ }
+ return 0;
+}
+
+void main() {
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]