[vala] Add has_copy_function and has_destroy_function struct attributes
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] Add has_copy_function and has_destroy_function struct attributes
- Date: Sun, 13 Sep 2009 18:39:50 +0000 (UTC)
commit 7092325a49472d5c108adb5f3e96623c75b77bbd
Author: Jürg Billeter <j bitron ch>
Date: Sun Sep 13 20:38:46 2009 +0200
Add has_copy_function and has_destroy_function struct attributes
codegen/valaccodebasemodule.vala | 121 ++++++++++++++++++++++++++++++++++++++
vala/valacodewriter.vala | 12 ++++
vala/valastruct.vala | 10 +++
vapigen/valagidlparser.vala | 24 ++++++++
4 files changed, 167 insertions(+), 0 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 0df998c..aa00179 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1990,6 +1990,10 @@ internal class Vala.CCodeBaseModule : CCodeModule {
var st = value_type.data_type as Struct;
if (st != null && st.is_disposable ()) {
+ if (!st.has_copy_function) {
+ generate_struct_copy_function (st);
+ }
+
var copy_call = new CCodeFunctionCall (new CCodeIdentifier (st.get_copy_function ()));
copy_call.add_argument (new CCodeIdentifier ("self"));
copy_call.add_argument (new CCodeIdentifier ("dup"));
@@ -2098,6 +2102,9 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
} else {
var st = (Struct) type.data_type;
+ if (!st.has_destroy_function) {
+ generate_struct_destroy_function (st);
+ }
unref_function = st.get_destroy_function ();
}
}
@@ -2903,6 +2910,10 @@ internal class Vala.CCodeBaseModule : CCodeModule {
copy_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr));
copy_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
+ if (!st.has_copy_function) {
+ generate_struct_copy_function (st);
+ }
+
var ccomma = new CCodeCommaExpression ();
if (st.get_copy_function () == "g_value_copy") {
@@ -4261,6 +4272,116 @@ internal class Vala.CCodeBaseModule : CCodeModule {
result.add_argument (expr);
return result;
}
+
+ void generate_struct_destroy_function (Struct st) {
+ if (source_declarations.add_declaration (st.get_destroy_function ())) {
+ // only generate function once per source file
+ return;
+ }
+
+ var function = new CCodeFunction (st.get_destroy_function (), "void");
+ function.modifiers = CCodeModifiers.STATIC;
+ function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*"));
+
+ var cblock = new CCodeBlock ();
+ foreach (Field f in st.get_fields ()) {
+ if (f.binding == MemberBinding.INSTANCE) {
+ if (requires_destroy (f.field_type)) {
+ var lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.get_cname ());
+
+ var this_access = new MemberAccess.simple ("this");
+ this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
+ this_access.ccodenode = new CCodeIdentifier ("(*self)");
+
+ var ma = new MemberAccess (this_access, f.name);
+ ma.symbol_reference = f;
+ cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (lhs, f.field_type, ma)));
+ }
+ }
+ }
+
+ source_declarations.add_type_member_declaration (function.copy ());
+ function.block = cblock;
+ source_type_member_definition.append (function);
+ }
+
+ void generate_struct_copy_function (Struct st) {
+ if (source_declarations.add_declaration (st.get_copy_function ())) {
+ // only generate function once per source file
+ return;
+ }
+
+ var function = new CCodeFunction (st.get_copy_function (), "void");
+ function.modifiers = CCodeModifiers.STATIC;
+ function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));
+ function.add_parameter (new CCodeFormalParameter ("dest", st.get_cname () + "*"));
+
+ int old_next_temp_var_id = next_temp_var_id;
+ var old_temp_vars = temp_vars;
+ var old_temp_ref_vars = temp_ref_vars;
+ var old_variable_name_map = variable_name_map;
+ next_temp_var_id = 0;
+ temp_vars = new ArrayList<LocalVariable> ();
+ temp_ref_vars = new ArrayList<LocalVariable> ();
+ variable_name_map = new HashMap<string,string> (str_hash, str_equal);
+
+ var cblock = new CCodeBlock ();
+ var cfrag = new CCodeFragment ();
+ cblock.add_statement (cfrag);
+
+ foreach (Field f in st.get_fields ()) {
+ if (f.binding == MemberBinding.INSTANCE) {
+ CCodeExpression copy = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.name);
+ if (requires_copy (f.field_type)) {
+ var this_access = new MemberAccess.simple ("this");
+ this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
+ this_access.ccodenode = new CCodeIdentifier ("(*self)");
+ var ma = new MemberAccess (this_access, f.name);
+ ma.symbol_reference = f;
+ copy = get_ref_cexpression (f.field_type, copy, ma, f);
+ }
+ var dest = new CCodeMemberAccess.pointer (new CCodeIdentifier ("dest"), f.name);
+
+ var array_type = f.field_type as ArrayType;
+ if (array_type != null && array_type.fixed_length) {
+ // fixed-length (stack-allocated) arrays
+ source_declarations.add_include ("string.h");
+
+ 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 array_copy_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+ array_copy_call.add_argument (dest);
+ array_copy_call.add_argument (copy);
+ array_copy_call.add_argument (size);
+ cblock.add_statement (new CCodeExpressionStatement (array_copy_call));
+ } else {
+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dest, copy)));
+
+ if (array_type != null && !f.no_array_length) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ var len_src = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), get_array_length_cname (f.name, dim));
+ var len_dest = new CCodeMemberAccess.pointer (new CCodeIdentifier ("dest"), get_array_length_cname (f.name, dim));
+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (len_dest, len_src)));
+ }
+ }
+ }
+ }
+ }
+
+ append_temp_decl (cfrag, temp_vars);
+ temp_vars.clear ();
+
+ next_temp_var_id = old_next_temp_var_id;
+ temp_vars = old_temp_vars;
+ temp_ref_vars = old_temp_ref_vars;
+ variable_name_map = old_variable_name_map;
+
+ source_declarations.add_type_member_declaration (function.copy ());
+ function.block = cblock;
+ source_type_member_definition.append (function);
+ }
}
// vim:sw=8 noet
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index 5a9cb10..ee294e5 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -320,6 +320,14 @@ public class Vala.CodeWriter : CodeVisitor {
write_string ("use_const = false, ");
}
+ if (!st.has_copy_function) {
+ write_string ("has_copy_function = false, ");
+ }
+
+ if (!st.has_destroy_function) {
+ write_string ("has_destroy_function = false, ");
+ }
+
write_string ("cheader_filename = \"%s\")]".printf (get_cheaders(st)));
write_newline ();
@@ -627,6 +635,10 @@ public class Vala.CodeWriter : CodeVisitor {
}
write_string ("array_length = false");
+
+ if (f.array_null_terminated) {
+ write_string (", array_null_terminated = true");
+ }
}
write_string (")]");
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
index 17ed9ec..2676322 100644
--- a/vala/valastruct.vala
+++ b/vala/valastruct.vala
@@ -96,6 +96,10 @@ public class Vala.Struct : TypeSymbol {
public bool signed { get; set; default = true; }
+ public bool has_copy_function { get; set; default = true; }
+
+ public bool has_destroy_function { get; set; default = true; }
+
/**
* Creates a new struct.
*
@@ -432,9 +436,15 @@ public class Vala.Struct : TypeSymbol {
if (a.has_argument ("copy_function")) {
set_copy_function (a.get_string ("copy_function"));
}
+ if (a.has_argument ("has_copy_function")) {
+ has_copy_function = a.get_bool ("has_copy_function");
+ }
if (a.has_argument ("destroy_function")) {
set_destroy_function (a.get_string ("destroy_function"));
}
+ if (a.has_argument ("has_destroy_function")) {
+ has_destroy_function = a.get_bool ("has_destroy_function");
+ }
if (a.has_argument ("use_const")) {
use_const = a.get_bool ("use_const");
}
diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala
index 914517d..b9f0214 100644
--- a/vapigen/valagidlparser.vala
+++ b/vapigen/valagidlparser.vala
@@ -436,6 +436,14 @@ public class Vala.GIdlParser : CodeVisitor {
}
} else if (nv[0] == "type_id") {
st.set_type_id (eval (nv[1]));
+ } else if (nv[0] == "has_copy_function") {
+ if (eval (nv[1]) == "0") {
+ st.has_copy_function = false;
+ }
+ } else if (nv[0] == "has_destroy_function") {
+ if (eval (nv[1]) == "0") {
+ st.has_destroy_function = false;
+ }
}
}
}
@@ -727,6 +735,14 @@ public class Vala.GIdlParser : CodeVisitor {
if (eval (nv[1]) == "0") {
st.use_const = false;
}
+ } else if (nv[0] == "has_copy_function") {
+ if (eval (nv[1]) == "0") {
+ st.has_copy_function = false;
+ }
+ } else if (nv[0] == "has_destroy_function") {
+ if (eval (nv[1]) == "0") {
+ st.has_destroy_function = false;
+ }
}
}
}
@@ -1877,6 +1893,7 @@ public class Vala.GIdlParser : CodeVisitor {
string cheader_filename = null;
string ctype = null;
+ bool array_null_terminated = false;
var attributes = get_attributes ("%s.%s".printf (current_data_type.get_cname (), node.name));
if (attributes != null) {
@@ -1909,6 +1926,10 @@ public class Vala.GIdlParser : CodeVisitor {
cheader_filename = eval (nv[1]);
} else if (nv[0] == "ctype") {
ctype = eval (nv[1]);
+ } else if (nv[0] == "array_null_terminated") {
+ if (eval (nv[1]) == "1") {
+ array_null_terminated = true;
+ }
}
}
}
@@ -1943,6 +1964,9 @@ public class Vala.GIdlParser : CodeVisitor {
}
field.no_array_length = true;
+ if (array_null_terminated) {
+ field.array_null_terminated = true;
+ }
return field;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]