vala r1832 - in trunk: . gobject
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r1832 - in trunk: . gobject
- Date: Sat, 11 Oct 2008 11:18:50 +0000 (UTC)
Author: juergbi
Date: Sat Oct 11 11:18:49 2008
New Revision: 1832
URL: http://svn.gnome.org/viewvc/vala?rev=1832&view=rev
Log:
2008-10-11 JÃrg Billeter <j bitron ch>
* gobject/valaccodegenerator.vala:
Add support for copying arrays, fixes bug 477107
Modified:
trunk/ChangeLog
trunk/gobject/valaccodegenerator.vala
Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala (original)
+++ trunk/gobject/valaccodegenerator.vala Sat Oct 11 11:18:49 2008
@@ -81,6 +81,7 @@
public int next_temp_var_id = 0;
private int current_try_id = 0;
private int next_try_id = 0;
+ private int next_array_dup_id = 0;
public bool in_creation_method = false;
private bool in_constructor = false;
public bool in_static_or_class_ctor = false;
@@ -1392,7 +1393,7 @@
dup_function = "";
}
} else {
- // duplicating non-reference counted structs may cause side-effects (and performance issues)
+ // duplicating non-reference counted objects may cause side-effects (and performance issues)
Report.error (source_reference, "duplicating %s instance, use weak variable or explicitly invoke copy method".printf (type.data_type.name));
return null;
}
@@ -1402,8 +1403,7 @@
string func_name = "%s_dup_func".printf (type.type_parameter.name.down ());
return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
} else if (type is ArrayType) {
- Report.error (source_reference, "internal error: duplicating %s instances not yet supported".printf (type.to_string ()));
- return null;
+ return new CCodeIdentifier (generate_array_dup_wrapper ((ArrayType) type));
} else if (type is PointerType) {
var pointer_type = (PointerType) type;
return get_dup_func_expression (pointer_type.base_type, source_reference);
@@ -1412,6 +1412,77 @@
}
}
+ string generate_array_dup_wrapper (ArrayType array_type) {
+ string dup_func = "_vala_array_dup%d".printf (++next_array_dup_id);
+
+ if (!add_wrapper (dup_func)) {
+ // wrapper already defined
+ return dup_func;
+ }
+
+ // declaration
+
+ var function = new CCodeFunction (dup_func, array_type.get_cname ());
+ function.modifiers = CCodeModifiers.STATIC;
+
+ function.add_parameter (new CCodeFormalParameter ("self", array_type.get_cname ()));
+ // total length over all dimensions
+ function.add_parameter (new CCodeFormalParameter ("length", "int"));
+
+ // definition
+
+ var block = new CCodeBlock ();
+
+ if (requires_copy (array_type.element_type)) {
+ var old_temp_vars = temp_vars;
+
+ var cdecl = new CCodeDeclaration (array_type.get_cname ());
+ var cvardecl = new CCodeVariableDeclarator ("result");
+ cdecl.add_declarator (cvardecl);
+ var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+ gnew.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
+ gnew.add_argument (new CCodeIdentifier ("length"));
+ cvardecl.initializer = gnew;
+ block.add_statement (cdecl);
+
+ var idx_decl = new CCodeDeclaration ("int");
+ idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
+ block.add_statement (idx_decl);
+
+ var loop_body = new CCodeBlock ();
+ loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
+
+ var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")), loop_body);
+ cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
+ cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
+ block.add_statement (cfor);
+
+ block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+
+ var cfrag = new CCodeFragment ();
+ append_temp_decl (cfrag, temp_vars);
+ block.add_statement (cfrag);
+ temp_vars = old_temp_vars;
+ } else {
+ var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
+ dup_call.add_argument (new CCodeIdentifier ("self"));
+
+ var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+ sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
+ dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("length"), sizeof_call));
+
+ block.add_statement (new CCodeReturnStatement (dup_call));
+ }
+
+ // append to file
+
+ source_type_member_declaration.append (function.copy ());
+
+ function.block = block;
+ source_type_member_definition.append (function);
+
+ return dup_func;
+ }
private string generate_struct_dup_wrapper (ValueType value_type) {
string dup_func = "_%sdup".printf (value_type.type_symbol.get_lower_case_cprefix ());
@@ -3092,7 +3163,7 @@
var ctemp = new CCodeIdentifier (decl.name);
var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, new CCodeConstant ("NULL"));
- if (expression_type.data_type == null) {
+ if (expression_type.type_parameter != null) {
if (!(current_type_symbol is Class)) {
return cexpr;
}
@@ -3102,11 +3173,27 @@
cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cisnull, cdupisnull);
}
- if (expression_type.data_type != null) {
- ccall.add_argument (ctemp);
- } else {
+ if (expression_type.type_parameter != null) {
// cast from gconstpointer to gpointer as GBoxedCopyFunc expects gpointer
ccall.add_argument (new CCodeCastExpression (ctemp, "gpointer"));
+ } else {
+ ccall.add_argument (ctemp);
+ }
+
+ if (expression_type is ArrayType) {
+ var array_type = (ArrayType) expression_type;
+ bool first = true;
+ CCodeExpression csizeexpr = null;
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ if (first) {
+ csizeexpr = get_array_length_cexpression (expr, dim);
+ first = false;
+ } else {
+ csizeexpr = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, csizeexpr, get_array_length_cexpression (expr, dim));
+ }
+ }
+
+ ccall.add_argument (csizeexpr);
}
var ccomma = new CCodeCommaExpression ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]