[vala] codegen: Don't copy array parameters when captured
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] codegen: Don't copy array parameters when captured
- Date: Mon, 9 Jan 2012 09:25:33 +0000 (UTC)
commit 15274701a10cb5425872cfc3d23ee62e6b660c84
Author: Luca Bruno <lucabru src gnome org>
Date: Fri Jan 6 22:57:02 2012 +0100
codegen: Don't copy array parameters when captured
Also allow uncopiable compact classes to be captured.
Fixes bug 639054.
codegen/valaccodebasemodule.vala | 30 ++++++++++++++++++++----------
codegen/valagasyncmodule.vala | 16 ++++++++--------
tests/Makefile.am | 1 +
tests/methods/bug639054.vala | 22 ++++++++++++++++++++++
4 files changed, 51 insertions(+), 18 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 338a685..002c79c 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1709,19 +1709,27 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
return result;
}
+ public bool no_implicit_copy (DataType type) {
+ // note: implicit copy of array is planned to be forbidden
+ var cl = type.data_type as Class;
+ return (type is DelegateType ||
+ type.is_array () ||
+ (cl != null && !cl.is_immutable && !is_reference_counting (cl) && !get_ccode_is_gboxed (cl)));
+ }
+
void capture_parameter (Parameter param, CCodeStruct data, int block_id) {
generate_type_declaration (param.variable_type, cfile);
var param_type = param.variable_type.copy ();
- param_type.value_owned = true;
+ if (!param.variable_type.value_owned) {
+ param_type.value_owned = !no_implicit_copy (param.variable_type);
+ }
data.add_field (get_ccode_name (param_type), get_variable_cname (param.name));
- bool is_unowned_delegate = param.variable_type is DelegateType && !param.variable_type.value_owned;
-
// create copy if necessary as captured variables may need to be kept alive
param.captured = false;
var value = load_parameter (param);
- if (requires_copy (param_type) && !param.variable_type.value_owned && !is_unowned_delegate) {
+ if (requires_copy (param_type) && !param.variable_type.value_owned) {
// directly access parameters in ref expressions
value = copy_value (value, param);
}
@@ -1974,11 +1982,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
foreach (var param in m.get_parameters ()) {
if (param.captured) {
var param_type = param.variable_type.copy ();
- param_type.value_owned = true;
-
- bool is_unowned_delegate = param.variable_type is DelegateType && !param.variable_type.value_owned;
+ if (!param_type.value_owned) {
+ param_type.value_owned = !no_implicit_copy (param_type);
+ }
- if (requires_destroy (param_type) && !is_unowned_delegate) {
+ if (requires_destroy (param_type)) {
bool old_coroutine = false;
if (m != null) {
old_coroutine = m.coroutine;
@@ -1998,11 +2006,13 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
if (!acc.readable && acc.value_parameter.captured) {
var param_type = acc.value_parameter.variable_type.copy ();
- param_type.value_owned = true;
+ if (!param_type.value_owned) {
+ param_type.value_owned = !no_implicit_copy (param_type);
+ }
bool is_unowned_delegate = acc.value_parameter.variable_type is DelegateType && !acc.value_parameter.variable_type.value_owned;
- if (requires_destroy (param_type) && !is_unowned_delegate) {
+ if (requires_destroy (param_type)) {
ccode.add_expression (destroy_parameter (acc.value_parameter));
}
}
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index 64ec2b5..c9da729 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -107,12 +107,12 @@ public class Vala.GAsyncModule : GSignalModule {
foreach (Parameter param in m.get_parameters ()) {
if (param.direction != ParameterDirection.OUT) {
- bool is_unowned_delegate = param.variable_type is DelegateType && !param.variable_type.value_owned;
-
var param_type = param.variable_type.copy ();
- param_type.value_owned = true;
+ if (!param_type.value_owned) {
+ param_type.value_owned = !no_implicit_copy (param_type);
+ }
- if (requires_destroy (param_type) && !is_unowned_delegate) {
+ if (requires_destroy (param_type)) {
// do not try to access closure blocks
bool old_captured = param.captured;
param.captured = false;
@@ -255,17 +255,17 @@ public class Vala.GAsyncModule : GSignalModule {
emit_context.push_symbol (m);
foreach (Parameter param in m.get_parameters ()) {
if (param.direction != ParameterDirection.OUT) {
- bool is_unowned_delegate = param.variable_type is DelegateType && !param.variable_type.value_owned;
-
var param_type = param.variable_type.copy ();
- param_type.value_owned = true;
+ if (!param_type.value_owned) {
+ param_type.value_owned = !no_implicit_copy (param_type);
+ }
// create copy if necessary as variables in async methods may need to be kept alive
var old_captured = param.captured;
param.captured = false;
current_method.coroutine = false;
var value = load_parameter (param);
- if (requires_copy (param_type) && !param.variable_type.value_owned && !is_unowned_delegate) {
+ if (requires_copy (param_type) && !param.variable_type.value_owned) {
value = copy_value (value, param);
}
current_method.coroutine = true;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 92b1ef0..fa5111e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -42,6 +42,7 @@ TESTS = \
methods/bug613483.vala \
methods/bug620673.vala \
methods/bug622570.vala \
+ methods/bug639054.vala \
methods/bug642899.vala \
methods/bug646345.vala \
methods/bug648320.vala \
diff --git a/tests/methods/bug639054.vala b/tests/methods/bug639054.vala
new file mode 100644
index 0000000..0ce93bd
--- /dev/null
+++ b/tests/methods/bug639054.vala
@@ -0,0 +1,22 @@
+[Compact]
+public class Baz {
+}
+
+public async void foo (uint8[] bar, Baz baz) {
+ SourceFunc f = () => {
+ bar[0] = 'b';
+ baz = null;
+ return false;
+ };
+ f ();
+}
+
+void main () {
+ var loop = new MainLoop ();
+ var bar = "foo".data;
+ foo.begin (bar, new Baz (), () => {
+ assert (bar[0] == 'b');
+ loop.quit ();
+ });
+ loop.run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]