vala r2151 - in trunk: . gobject vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r2151 - in trunk: . gobject vala
- Date: Mon, 15 Dec 2008 08:19:39 +0000 (UTC)
Author: juergbi
Date: Mon Dec 15 08:19:39 2008
New Revision: 2151
URL: http://svn.gnome.org/viewvc/vala?rev=2151&view=rev
Log:
2008-12-15 JÃrg Billeter <j bitron ch>
* vala/valastruct.vala:
* gobject/Makefile.am:
* gobject/valaccodebasemodule.vala:
* gobject/valaccodestructmodule.vala:
* gobject/valagtypemodule.vala:
* gobject/valastructregisterfunction.vala:
* gobject/valatyperegisterfunction.vala:
Register structs as boxed types, generate dup, copy, and free
functions, fixes bug 548864
Added:
trunk/gobject/valastructregisterfunction.vala
Modified:
trunk/ChangeLog
trunk/gobject/Makefile.am
trunk/gobject/valaccodebasemodule.vala
trunk/gobject/valaccodestructmodule.vala
trunk/gobject/valagtypemodule.vala
trunk/gobject/valatyperegisterfunction.vala
trunk/vala/valastruct.vala
Modified: trunk/gobject/Makefile.am
==============================================================================
--- trunk/gobject/Makefile.am (original)
+++ trunk/gobject/Makefile.am Mon Dec 15 08:19:39 2008
@@ -35,6 +35,7 @@
valagtypemodule.vala \
valagasyncmodule.vala \
valainterfaceregisterfunction.vala \
+ valastructregisterfunction.vala \
valatyperegisterfunction.vala \
$(NULL)
Modified: trunk/gobject/valaccodebasemodule.vala
==============================================================================
--- trunk/gobject/valaccodebasemodule.vala (original)
+++ trunk/gobject/valaccodebasemodule.vala Mon Dec 15 08:19:39 2008
@@ -1532,9 +1532,10 @@
// allow duplicates of immutable instances as for example strings
dup_function = type.data_type.get_dup_function ();
} else if (type is ValueType) {
- if (type.nullable) {
+ dup_function = type.data_type.get_dup_function ();
+ if (dup_function == null && type.nullable) {
dup_function = generate_struct_dup_wrapper ((ValueType) type);
- } else {
+ } else if (dup_function == null) {
dup_function = "";
}
} else {
@@ -1941,10 +1942,9 @@
var cfrag = new CCodeFragment ();
append_temp_decl (cfrag, temp_vars);
- // FIXME cast to CodeNode shouldn't be necessary as Statement requires CodeNode
- cfrag.append (((CodeNode) stmt).ccodenode);
+ cfrag.append (stmt.ccodenode);
- ((CodeNode) stmt).ccodenode = cfrag;
+ stmt.ccodenode = cfrag;
}
public void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop) {
@@ -2377,7 +2377,15 @@
ccomma.append_expression (copy_call);
ccomma.append_expression (ctemp);
- return ccomma;
+ if (expression_type.data_type == gvalue_type) {
+ // g_value_init/copy must not be called for uninitialized values
+ var cisvalid = new CCodeFunctionCall (new CCodeIdentifier ("G_IS_VALUE"));
+ cisvalid.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr));
+
+ return new CCodeConditionalExpression (cisvalid, ccomma, cexpr);
+ } else {
+ return ccomma;
+ }
}
/* (temp = expr, temp == NULL ? NULL : ref (temp))
Modified: trunk/gobject/valaccodestructmodule.vala
==============================================================================
--- trunk/gobject/valaccodestructmodule.vala (original)
+++ trunk/gobject/valaccodestructmodule.vala Mon Dec 15 08:19:39 2008
@@ -62,11 +62,93 @@
add_struct_destroy_function (st);
}
+ add_struct_dup_function (st);
+ add_struct_free_function (st);
+
current_type_symbol = old_type_symbol;
instance_struct = old_instance_struct;
instance_finalize_fragment = old_instance_finalize_fragment;
}
+ void add_struct_dup_function (Struct st) {
+ var function = new CCodeFunction (st.get_dup_function (), st.get_cname () + "*");
+ if (st.access == SymbolAccessibility.PRIVATE) {
+ function.modifiers = CCodeModifiers.STATIC;
+ }
+
+ function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));
+
+ if (st.access != SymbolAccessibility.PRIVATE) {
+ header_type_member_declaration.append (function.copy ());
+ } else {
+ source_type_member_declaration.append (function.copy ());
+ }
+
+ var cblock = new CCodeBlock ();
+
+ var cdecl = new CCodeDeclaration (st.get_cname () + "*");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("dup"));
+ cblock.add_statement (cdecl);
+
+ var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+ creation_call.add_argument (new CCodeConstant (st.get_cname ()));
+ creation_call.add_argument (new CCodeConstant ("1"));
+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("dup"), creation_call)));
+
+ if (st.is_disposable ()) {
+ 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"));
+ cblock.add_statement (new CCodeExpressionStatement (copy_call));
+ } else {
+ var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+ sizeof_call.add_argument (new CCodeConstant (st.get_cname ()));
+
+ var copy_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+ copy_call.add_argument (new CCodeIdentifier ("dup"));
+ copy_call.add_argument (new CCodeIdentifier ("self"));
+ copy_call.add_argument (sizeof_call);
+ cblock.add_statement (new CCodeExpressionStatement (copy_call));
+ }
+
+ cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("dup")));
+
+ function.block = cblock;
+
+ source_type_member_definition.append (function);
+ }
+
+ void add_struct_free_function (Struct st) {
+ var function = new CCodeFunction (st.get_free_function (), "void");
+ if (st.access == SymbolAccessibility.PRIVATE) {
+ function.modifiers = CCodeModifiers.STATIC;
+ }
+
+ function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*"));
+
+ if (st.access != SymbolAccessibility.PRIVATE) {
+ header_type_member_declaration.append (function.copy ());
+ } else {
+ source_type_member_declaration.append (function.copy ());
+ }
+
+ var cblock = new CCodeBlock ();
+
+ if (st.is_disposable ()) {
+ var destroy_call = new CCodeFunctionCall (new CCodeIdentifier (st.get_destroy_function ()));
+ destroy_call.add_argument (new CCodeIdentifier ("self"));
+ cblock.add_statement (new CCodeExpressionStatement (destroy_call));
+ }
+
+ var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
+ free_call.add_argument (new CCodeIdentifier ("self"));
+ cblock.add_statement (new CCodeExpressionStatement (free_call));
+
+ function.block = cblock;
+
+ source_type_member_definition.append (function);
+ }
+
void add_struct_copy_function (Struct st) {
var function = new CCodeFunction (st.get_copy_function (), "void");
if (st.access == SymbolAccessibility.PRIVATE) {
@@ -83,6 +165,22 @@
}
var cblock = new CCodeBlock ();
+ var cfrag = new CCodeFragment ();
+ cblock.add_statement (cfrag);
+
+ foreach (var 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)) {
+ copy = get_ref_cexpression (f.field_type, copy, null, f);
+ }
+ var dest = new CCodeMemberAccess.pointer (new CCodeIdentifier ("dest"), f.name);
+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dest, copy)));
+ }
+ }
+
+ append_temp_decl (cfrag, temp_vars);
+ temp_vars.clear ();
function.block = cblock;
Modified: trunk/gobject/valagtypemodule.vala
==============================================================================
--- trunk/gobject/valagtypemodule.vala (original)
+++ trunk/gobject/valagtypemodule.vala Mon Dec 15 08:19:39 2008
@@ -142,4 +142,28 @@
source_type_member_definition.append (base_init);
}
+
+ public override void visit_struct (Struct st) {
+ base.visit_struct (st);
+
+ CCodeFragment decl_frag;
+ if (st.access != SymbolAccessibility.PRIVATE) {
+ decl_frag = header_type_declaration;
+ } else {
+ decl_frag = source_type_declaration;
+ }
+
+ decl_frag.append (new CCodeNewline ());
+ var macro = "(%s_get_type ())".printf (st.get_lower_case_cname (null));
+ decl_frag.append (new CCodeMacroReplacement (st.get_type_id (), macro));
+
+ var type_fun = new StructRegisterFunction (st, context);
+ type_fun.init_from_type (false);
+ if (st.access != SymbolAccessibility.PRIVATE) {
+ header_type_member_declaration.append (type_fun.get_declaration ());
+ } else {
+ source_type_member_declaration.append (type_fun.get_declaration ());
+ }
+ source_type_member_definition.append (type_fun.get_definition ());
+ }
}
Added: trunk/gobject/valastructregisterfunction.vala
==============================================================================
--- (empty file)
+++ trunk/gobject/valastructregisterfunction.vala Mon Dec 15 08:19:39 2008
@@ -0,0 +1,56 @@
+/* valastructregisterfunction.vala
+ *
+ * Copyright (C) 2008 JÃrg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * JÃrg Billeter <j bitron ch>
+ */
+
+using GLib;
+
+/**
+ * C function to register a class at runtime.
+ */
+public class Vala.StructRegisterFunction : TypeRegisterFunction {
+ /**
+ * Specifies the struct to be registered.
+ */
+ public weak Struct struct_reference { get; set; }
+
+ /**
+ * Creates a new C function to register the specified class at runtime.
+ *
+ * @param cl a class
+ * @return newly created class register function
+ */
+ public StructRegisterFunction (Struct st, CodeContext context) {
+ struct_reference = st;
+ this.context = context;
+ }
+
+ public override TypeSymbol get_type_declaration () {
+ return struct_reference;
+ }
+
+ public override SymbolAccessibility get_accessibility () {
+ return struct_reference.access;
+ }
+
+ public override CCodeFragment get_type_interface_init_statements () {
+ return new CCodeFragment ();
+ }
+}
Modified: trunk/gobject/valatyperegisterfunction.vala
==============================================================================
--- trunk/gobject/valatyperegisterfunction.vala (original)
+++ trunk/gobject/valatyperegisterfunction.vala Mon Dec 15 08:19:39 2008
@@ -92,11 +92,11 @@
string type_value_table_decl_name = null;
var type_init = new CCodeBlock ();
- if ( fundamental ) {
+ if (fundamental) {
var cgtypetabledecl = new CCodeDeclaration ("const GTypeValueTable");
cgtypetabledecl.modifiers = CCodeModifiers.STATIC;
- cgtypetabledecl.add_declarator ( new CCodeVariableDeclarator.with_initializer ( "g_define_type_value_table", new CCodeConstant ("{ %s, %s, %s, %s, \"p\", %s, \"p\", %s }".printf ( get_gtype_value_table_init_function_name (), get_gtype_value_table_free_function_name (), get_gtype_value_table_copy_function_name (), get_gtype_value_table_peek_pointer_function_name (), get_gtype_value_table_collect_value_function_name (), get_gtype_value_table_lcopy_value_function_name () ))));
+ cgtypetabledecl.add_declarator (new CCodeVariableDeclarator.with_initializer ( "g_define_type_value_table", new CCodeConstant ("{ %s, %s, %s, %s, \"p\", %s, \"p\", %s }".printf (get_gtype_value_table_init_function_name (), get_gtype_value_table_free_function_name (), get_gtype_value_table_copy_function_name (), get_gtype_value_table_peek_pointer_function_name (), get_gtype_value_table_collect_value_function_name (), get_gtype_value_table_lcopy_value_function_name ()))));
type_value_table_decl_name = "&g_define_type_value_table";
type_init.add_statement ( cgtypetabledecl );
}
@@ -105,39 +105,47 @@
}
- var ctypedecl = new CCodeDeclaration ("const GTypeInfo");
- ctypedecl.modifiers = CCodeModifiers.STATIC;
- ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) NULL, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_func_name (), get_class_init_func_name (), get_instance_struct_size (), get_instance_init_func_name (), type_value_table_decl_name))));
- type_init.add_statement (ctypedecl);
- if (fundamental) {
- var ctypefundamentaldecl = new CCodeDeclaration ("const GTypeFundamentalInfo");
- ctypefundamentaldecl.modifiers = CCodeModifiers.STATIC;
- ctypefundamentaldecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_fundamental_info", new CCodeConstant ("{ (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }")));
- type_init.add_statement (ctypefundamentaldecl);
+ if (get_type_declaration () is ObjectTypeSymbol) {
+ var ctypedecl = new CCodeDeclaration ("const GTypeInfo");
+ ctypedecl.modifiers = CCodeModifiers.STATIC;
+ ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) NULL, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_func_name (), get_class_init_func_name (), get_instance_struct_size (), get_instance_init_func_name (), type_value_table_decl_name))));
+ type_init.add_statement (ctypedecl);
+ if (fundamental) {
+ var ctypefundamentaldecl = new CCodeDeclaration ("const GTypeFundamentalInfo");
+ ctypefundamentaldecl.modifiers = CCodeModifiers.STATIC;
+ ctypefundamentaldecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_fundamental_info", new CCodeConstant ("{ (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }")));
+ type_init.add_statement (ctypefundamentaldecl);
+ }
}
type_init.add_statement (get_type_interface_init_declaration ());
CCodeFunctionCall reg_call;
- if (fundamental) {
+ if (get_type_declaration () is Struct) {
+ reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_boxed_type_register_static"));
+ } else if (fundamental) {
reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_register_fundamental"));
+ reg_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("g_type_fundamental_next")));
} else if (!plugin) {
reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_register_static"));
+ reg_call.add_argument (new CCodeIdentifier (get_parent_type_name ()));
} else {
reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_module_register_type"));
reg_call.add_argument (new CCodeIdentifier ("module"));
- }
- if (fundamental) {
- reg_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("g_type_fundamental_next")));
- } else {
reg_call.add_argument (new CCodeIdentifier (get_parent_type_name ()));
}
reg_call.add_argument (new CCodeConstant ("\"%s\"".printf (get_type_declaration ().get_cname ())));
- reg_call.add_argument (new CCodeIdentifier ("&g_define_type_info"));
- if (fundamental) {
- reg_call.add_argument (new CCodeIdentifier ("&g_define_type_fundamental_info"));
+ if (get_type_declaration () is Struct) {
+ var st = (Struct) get_type_declaration ();
+ reg_call.add_argument (new CCodeCastExpression (new CCodeIdentifier (st.get_dup_function ()), "GBoxedCopyFunc"));
+ reg_call.add_argument (new CCodeCastExpression (new CCodeIdentifier (st.get_free_function ()), "GBoxedFreeFunc"));
+ } else {
+ reg_call.add_argument (new CCodeIdentifier ("&g_define_type_info"));
+ if (fundamental) {
+ reg_call.add_argument (new CCodeIdentifier ("&g_define_type_fundamental_info"));
+ }
+ reg_call.add_argument (new CCodeConstant (get_type_flags ()));
}
- reg_call.add_argument (new CCodeConstant (get_type_flags ()));
if (use_thread_safe && !plugin) {
var temp_decl = new CCodeDeclaration ("GType");
@@ -197,42 +205,54 @@
*
* @return C struct name
*/
- public abstract string get_type_struct_name ();
+ public virtual string get_type_struct_name () {
+ assert_not_reached ();
+ }
/**
* Returns the name of the base_init function in C code.
*
* @return C function name
*/
- public abstract string get_base_init_func_name ();
+ public virtual string get_base_init_func_name () {
+ assert_not_reached ();
+ }
/**
* Returns the name of the class_init function in C code.
*
* @return C function name
*/
- public abstract string get_class_init_func_name ();
+ public virtual string get_class_init_func_name () {
+ assert_not_reached ();
+ }
/**
* Returns the size of the instance struct in C code.
*
* @return C instance struct size
*/
- public abstract string get_instance_struct_size ();
+ public virtual string get_instance_struct_size () {
+ assert_not_reached ();
+ }
/**
* Returns the name of the instance_init function in C code.
*
* @return C function name
*/
- public abstract string get_instance_init_func_name ();
+ public virtual string get_instance_init_func_name () {
+ assert_not_reached ();
+ }
/**
* Returns the name of the parent type in C code.
*
* @return C function name
*/
- public abstract string get_parent_type_name ();
+ public virtual string get_parent_type_name () {
+ assert_not_reached ();
+ }
Modified: trunk/vala/valastruct.vala
==============================================================================
--- trunk/vala/valastruct.vala (original)
+++ trunk/vala/valastruct.vala Mon Dec 15 08:19:39 2008
@@ -373,16 +373,21 @@
public override string? get_type_id () {
if (type_id == null) {
- foreach (DataType type in base_types) {
- var st = type.data_type as Struct;
- if (st != null) {
- return st.get_type_id ();;
+ // TODO use attribute check instead
+ if (external_package) {
+ foreach (DataType type in base_types) {
+ var st = type.data_type as Struct;
+ if (st != null) {
+ return st.get_type_id ();;
+ }
+ }
+ if (is_simple_type ()) {
+ Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (get_full_name ()));
+ } else {
+ return "G_TYPE_POINTER";
}
- }
- if (is_simple_type ()) {
- Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (get_full_name ()));
} else {
- return "G_TYPE_POINTER";
+ type_id = get_upper_case_cname ("TYPE_");
}
}
return type_id;
@@ -555,6 +560,24 @@
return false;
}
+ public override string? get_dup_function () {
+ // TODO use attribute check instead
+ if (external_package) {
+ return null;
+ } else {
+ return get_lower_case_cprefix () + "dup";
+ }
+ }
+
+ public override string? get_free_function () {
+ // TODO use attribute check instead
+ if (external_package) {
+ return null;
+ } else {
+ return get_lower_case_cprefix () + "free";
+ }
+ }
+
public string get_default_copy_function () {
return get_lower_case_cprefix () + "copy";
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]