[vala] codegen: Fix capturing generic variables having instance type parameters
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] codegen: Fix capturing generic variables having instance type parameters
- Date: Tue, 1 Nov 2011 11:07:01 +0000 (UTC)
commit 7ec69c78840cd3a5fe88de35784a9a3592c7b5dc
Author: Luca Bruno <lucabru src gnome org>
Date: Tue Nov 1 11:54:14 2011 +0100
codegen: Fix capturing generic variables having instance type parameters
Fixes bug 663134.
codegen/valaccodebasemodule.vala | 41 +++++++++++++++++++++++++++----------
tests/Makefile.am | 1 +
tests/objects/bug663134.vala | 20 ++++++++++++++++++
3 files changed, 51 insertions(+), 11 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 47d3004..d008e1f 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1905,18 +1905,21 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_ref_count_")));
ccode.open_if (ccall);
- if (parent_block != null) {
- int parent_block_id = get_block_id (parent_block);
-
- var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (parent_block_id)));
- unref_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)));
- ccode.add_expression (unref_call);
- ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), new CCodeConstant ("NULL"));
- } else {
- if (get_this_type () != null) {
- var this_value = new GLibValue (get_data_type_for_symbol (current_type_symbol), new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "self"), true);
- ccode.add_expression (destroy_value (this_value));
+ if (get_this_type () != null) {
+ // assign "self" for type parameters
+ CCodeExpression cself = new CCodeIdentifier ("_data%d_".printf (block_id));
+ unowned Block parent_closure_block = b;
+ while (true) {
+ parent_closure_block = next_closure_block (parent_closure_block.parent_symbol);
+ if (parent_closure_block == null) {
+ break;
+ }
+ int parent_block_id = get_block_id (parent_closure_block);
+ cself = new CCodeMemberAccess.pointer (cself, "_data%d_".printf (parent_block_id));
}
+ cself = new CCodeMemberAccess.pointer (cself, "self");
+ ccode.add_declaration ("%s *".printf (get_ccode_name (current_type_symbol)), new CCodeVariableDeclarator ("self"));
+ ccode.add_assignment (new CCodeIdentifier ("self"), cself);
}
// free in reverse order
@@ -1980,6 +1983,22 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
}
+ // free parent block and "self" after captured variables
+ // because they may require type parameters
+ if (parent_block != null) {
+ int parent_block_id = get_block_id (parent_block);
+
+ var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (parent_block_id)));
+ unref_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)));
+ ccode.add_expression (unref_call);
+ ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), new CCodeConstant ("NULL"));
+ } else {
+ if (get_this_type () != null) {
+ var this_value = new GLibValue (get_data_type_for_symbol (current_type_symbol), new CCodeIdentifier ("self"), true);
+ ccode.add_expression (destroy_value (this_value));
+ }
+ }
+
var data_free = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
data_free.add_argument (new CCodeIdentifier (struct_name));
data_free.add_argument (new CCodeIdentifier ("_data%d_".printf (block_id)));
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4185195..180cacc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -115,6 +115,7 @@ TESTS = \
objects/bug646792.vala \
objects/bug653138.vala \
objects/bug654702.vala \
+ objects/bug663134.vala \
errors/errors.vala \
errors/bug567181.vala \
errors/bug579101.vala \
diff --git a/tests/objects/bug663134.vala b/tests/objects/bug663134.vala
new file mode 100644
index 0000000..fe8cc00
--- /dev/null
+++ b/tests/objects/bug663134.vala
@@ -0,0 +1,20 @@
+public class Foo<T> {
+ public void bar () {
+ T baz = null;
+ SourceFunc f = () => {
+ baz = null;
+ SourceFunc ff = () => {
+ baz = null;
+ return false;
+ };
+ ff ();
+ return false;
+ };
+ f ();
+ }
+}
+
+void main () {
+ var foo = new Foo<string> ();
+ foo.bar ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]