From: Jürg Billeter Date: Fri, 21 Nov 2008 22:28:07 +0000 (+0000) Subject: Various coroutine code generation improvements X-Git-Tag: VALA_0_5_2~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7a06bd1eaad448073ebf479f3b9b5ddd1f39a38;p=thirdparty%2Fvala.git Various coroutine code generation improvements 2008-11-21 Jürg Billeter * vala/valamethod.vala: * gobject/valaccodemethodcallmodule.vala: * gobject/valaccodemethodmodule.vala: * gobject/valadbusclientmodule.vala: * gobject/valagasyncmodule.vala: Various coroutine code generation improvements svn path=/trunk/; revision=2056 --- diff --git a/ChangeLog b/ChangeLog index 41685bf6b..2985ff8d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-11-21 Jürg Billeter + + * vala/valamethod.vala: + * gobject/valaccodemethodcallmodule.vala: + * gobject/valaccodemethodmodule.vala: + * gobject/valadbusclientmodule.vala: + * gobject/valagasyncmodule.vala: + + Various coroutine code generation improvements + 2008-11-21 Jürg Billeter * gobject/valaccodemethodmodule.vala: diff --git a/gobject/valaccodemethodcallmodule.vala b/gobject/valaccodemethodcallmodule.vala index 5d4d9cc42..ccb3dd68b 100644 --- a/gobject/valaccodemethodcallmodule.vala +++ b/gobject/valaccodemethodcallmodule.vala @@ -348,13 +348,18 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { } if (m != null && m.coroutine) { - if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) { - // asynchronous begin call - carg_map.set (get_param_pos (-1), new CCodeConstant ("NULL")); - carg_map.set (get_param_pos (-0.9), new CCodeConstant ("NULL")); - } else { - carg_map.set (get_param_pos (-1), new CCodeIdentifier (current_method.get_cname () + "_ready")); - carg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("data")); + if ((current_method != null && current_method.coroutine) + || (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference)) { + // asynchronous call + var cid = (CCodeIdentifier) ccall.call; + cid.name += "_async"; + if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) { + carg_map.set (get_param_pos (-1), new CCodeConstant ("NULL")); + carg_map.set (get_param_pos (-0.9), new CCodeConstant ("NULL")); + } else { + carg_map.set (get_param_pos (-1), new CCodeIdentifier (current_method.get_cname () + "_ready")); + carg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("data")); + } } } diff --git a/gobject/valaccodemethodmodule.vala b/gobject/valaccodemethodmodule.vala index 8d7e4c69d..633f93efc 100644 --- a/gobject/valaccodemethodmodule.vala +++ b/gobject/valaccodemethodmodule.vala @@ -37,10 +37,6 @@ public class Vala.CCodeMethodModule : CCodeStructModule { } public override string? get_custom_creturn_type (Method m) { - if (m.coroutine) { - return "gboolean"; - } - var attr = m.get_attribute ("CCode"); if (attr != null) { string type = attr.get_string ("type"); @@ -167,61 +163,14 @@ public class Vala.CCodeMethodModule : CCodeStructModule { var cparam_map = new HashMap (direct_hash, direct_equal); CCodeFunctionDeclarator vdeclarator = null; - - if (m.parent_symbol is Class && m is CreationMethod) { - var cl = (Class) m.parent_symbol; - if (!cl.is_compact) { - cparam_map.set (get_param_pos (m.cinstance_parameter_position), new CCodeFormalParameter ("object_type", "GType")); - } - } else if (m.binding == MemberBinding.INSTANCE || (m.parent_symbol is Struct && m is CreationMethod)) { - TypeSymbol parent_type = find_parent_type (m); - DataType this_type; - if (parent_type is Class) { - this_type = new ObjectType ((Class) parent_type); - } else if (parent_type is Interface) { - this_type = new ObjectType ((Interface) parent_type); - } else { - this_type = new ValueType (parent_type); - } - - CCodeFormalParameter instance_param = null; - if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) { - var base_type = new ObjectType ((Interface) m.base_interface_method.parent_symbol); - instance_param = new CCodeFormalParameter ("base", base_type.get_cname ()); - } else if (m.overrides) { - var base_type = new ObjectType ((Class) m.base_method.parent_symbol); - instance_param = new CCodeFormalParameter ("base", base_type.get_cname ()); - } else { - if (m.parent_symbol is Struct && !((Struct) m.parent_symbol).is_simple_type ()) { - instance_param = new CCodeFormalParameter ("*self", this_type.get_cname ()); - } else { - instance_param = new CCodeFormalParameter ("self", this_type.get_cname ()); - } - } - cparam_map.set (get_param_pos (m.cinstance_parameter_position), instance_param); - - if (m.is_abstract || m.is_virtual) { - var vdecl = new CCodeDeclaration (get_creturn_type (m, creturn_type.get_cname ())); - vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name); - vdecl.add_declarator (vdeclarator); - type_struct.add_declaration (vdecl); - } - } else if (m.binding == MemberBinding.CLASS) { - TypeSymbol parent_type = find_parent_type (m); - DataType this_type; - this_type = new ClassType ((Class) parent_type); - var class_param = new CCodeFormalParameter ("klass", this_type.get_cname ()); - cparam_map.set (get_param_pos (m.cinstance_parameter_position), class_param); + if (m.is_abstract || m.is_virtual) { + var vdecl = new CCodeDeclaration (get_creturn_type (m, creturn_type.get_cname ())); + vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); } - if (!m.coroutine) { - generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, function, vdeclarator); - } else { - // data struct to hold parameters, local variables, and the return value - cparam_map.set (get_param_pos (0), new CCodeFormalParameter ("data", Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data*")); - - generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, function, vdeclarator, null, null, 0); - } + generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, function, vdeclarator); bool visible = !m.is_internal_symbol (); @@ -249,6 +198,14 @@ public class Vala.CCodeMethodModule : CCodeStructModule { function.block.prepend_statement (cinit); if (m.coroutine) { + var co_function = new CCodeFunction (m.get_real_cname () + "_co", "gboolean"); + + // data struct to hold parameters, local variables, and the return value + co_function.add_parameter (new CCodeFormalParameter ("data", Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data*")); + + co_function.modifiers |= CCodeModifiers.STATIC; + source_type_member_declaration.append (co_function.copy ()); + var cswitch = new CCodeSwitchStatement (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state")); // initial coroutine state @@ -275,8 +232,10 @@ public class Vala.CCodeMethodModule : CCodeStructModule { cswitch.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE"))); - function.block = new CCodeBlock (); - function.block.add_statement (cswitch); + co_function.block = new CCodeBlock (); + co_function.block.add_statement (cswitch); + + source_type_member_definition.append (co_function); } if (m.parent_symbol is Class) { @@ -478,19 +437,9 @@ public class Vala.CCodeMethodModule : CCodeStructModule { var vfunc = new CCodeFunction (m.get_cname (), creturn_type.get_cname ()); vfunc.line = function.line; - ReferenceType this_type; - if (m.parent_symbol is Class) { - this_type = new ObjectType ((Class) m.parent_symbol); - } else { - this_type = new ObjectType ((Interface) m.parent_symbol); - } - cparam_map = new HashMap (direct_hash, direct_equal); var carg_map = new HashMap (direct_hash, direct_equal); - var cparam = new CCodeFormalParameter ("self", this_type.get_cname ()); - cparam_map.set (get_param_pos (m.cinstance_parameter_position), cparam); - var vblock = new CCodeBlock (); foreach (Expression precondition in m.get_preconditions ()) { @@ -599,6 +548,45 @@ public class Vala.CCodeMethodModule : CCodeStructModule { } public override void generate_cparameters (Method m, DataType creturn_type, bool in_gtypeinstance_creation_method, Map cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) { + if (m.parent_symbol is Class && m is CreationMethod) { + var cl = (Class) m.parent_symbol; + if (!cl.is_compact && vcall == null) { + cparam_map.set (get_param_pos (m.cinstance_parameter_position), new CCodeFormalParameter ("object_type", "GType")); + } + } else if (m.binding == MemberBinding.INSTANCE || (m.parent_symbol is Struct && m is CreationMethod)) { + TypeSymbol parent_type = find_parent_type (m); + DataType this_type; + if (parent_type is Class) { + this_type = new ObjectType ((Class) parent_type); + } else if (parent_type is Interface) { + this_type = new ObjectType ((Interface) parent_type); + } else { + this_type = new ValueType (parent_type); + } + + CCodeFormalParameter instance_param = null; + if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) { + var base_type = new ObjectType ((Interface) m.base_interface_method.parent_symbol); + instance_param = new CCodeFormalParameter ("base", base_type.get_cname ()); + } else if (m.overrides) { + var base_type = new ObjectType ((Class) m.base_method.parent_symbol); + instance_param = new CCodeFormalParameter ("base", base_type.get_cname ()); + } else { + if (m.parent_symbol is Struct && !((Struct) m.parent_symbol).is_simple_type ()) { + instance_param = new CCodeFormalParameter ("*self", this_type.get_cname ()); + } else { + instance_param = new CCodeFormalParameter ("self", this_type.get_cname ()); + } + } + cparam_map.set (get_param_pos (m.cinstance_parameter_position), instance_param); + } else if (m.binding == MemberBinding.CLASS) { + TypeSymbol parent_type = find_parent_type (m); + DataType this_type; + this_type = new ClassType ((Class) parent_type); + var class_param = new CCodeFormalParameter ("klass", this_type.get_cname ()); + cparam_map.set (get_param_pos (m.cinstance_parameter_position), class_param); + } + if (in_gtypeinstance_creation_method) { // memory management for generic types int type_param_index = 0; diff --git a/gobject/valadbusclientmodule.vala b/gobject/valadbusclientmodule.vala index 21e3ac996..eb23e8623 100644 --- a/gobject/valadbusclientmodule.vala +++ b/gobject/valadbusclientmodule.vala @@ -52,9 +52,6 @@ public class Vala.DBusClientModule : DBusModule { var cparam_map = new HashMap (direct_hash, direct_equal); - var instance_param = new CCodeFormalParameter ("obj", dynamic_method.dynamic_type.get_cname ()); - cparam_map.set (get_param_pos (method.cinstance_parameter_position), instance_param); - generate_cparameters (method, method.return_type, false, cparam_map, func); var block = new CCodeBlock (); @@ -78,7 +75,7 @@ public class Vala.DBusClientModule : DBusModule { var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_begin_call")); - ccall.add_argument (new CCodeIdentifier ("obj")); + ccall.add_argument (new CCodeIdentifier ("self")); bool found_out = false; Expression callback = null; diff --git a/gobject/valagasyncmodule.vala b/gobject/valagasyncmodule.vala index 3a2423187..9458ad5da 100644 --- a/gobject/valagasyncmodule.vala +++ b/gobject/valagasyncmodule.vala @@ -61,7 +61,7 @@ public class Vala.GAsyncModule : GSignalModule { source_type_declaration.append (new CCodeTypeDefinition ("struct _" + dataname, new CCodeVariableDeclarator (dataname))); // generate async function - var asyncfunc = new CCodeFunction (m.get_cname (), "void"); + var asyncfunc = new CCodeFunction (m.get_real_cname () + "_async", "void"); asyncfunc.line = function.line; var cparam_map = new HashMap (direct_hash, direct_equal); @@ -80,31 +80,43 @@ public class Vala.GAsyncModule : GSignalModule { asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"), new CCodeIdentifier ("user_data")))); foreach (FormalParameter param in m.get_parameters ()) { - asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), param.name), new CCodeIdentifier (param.name)))); + if (param.direction != ParameterDirection.OUT) { + asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), param.name), new CCodeIdentifier (param.name)))); + } } - var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ())); + var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname () + "_co")); ccall.add_argument (new CCodeIdentifier ("data")); asyncblock.add_statement (new CCodeExpressionStatement (ccall)); cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("callback", "GAsyncReadyCallback")); cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("user_data", "gpointer")); - generate_cparameters (m, creturn_type, false, cparam_map, asyncfunc, null, null, null, 1); - - if (visible) { - header_type_member_declaration.append (asyncfunc.copy ()); - } else { - asyncfunc.modifiers |= CCodeModifiers.STATIC; - source_type_member_declaration.append (asyncfunc.copy ()); + CCodeFunctionDeclarator vdeclarator = null; + if (m.is_abstract || m.is_virtual) { + var vdecl = new CCodeDeclaration ("void"); + vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name + "_async"); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); } + + generate_cparameters (m, creturn_type, false, cparam_map, asyncfunc, vdeclarator, null, null, 1); + + if (!m.is_abstract) { + if (visible && m.base_method == null && m.base_interface_method == null) { + header_type_member_declaration.append (asyncfunc.copy ()); + } else { + asyncfunc.modifiers |= CCodeModifiers.STATIC; + source_type_member_declaration.append (asyncfunc.copy ()); + } - asyncfunc.block = asyncblock; + asyncfunc.block = asyncblock; - source_type_member_definition.append (asyncfunc); + source_type_member_definition.append (asyncfunc); + } // generate finish function - var finishfunc = new CCodeFunction (m.get_cname () + "_finish", creturn_type.get_cname ()); + var finishfunc = new CCodeFunction (m.get_real_cname () + "_finish", creturn_type.get_cname ()); finishfunc.line = function.line; cparam_map = new HashMap (direct_hash, direct_equal); @@ -113,45 +125,56 @@ public class Vala.GAsyncModule : GSignalModule { cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("res", "GAsyncResult*")); - generate_cparameters (m, creturn_type, false, cparam_map, finishfunc, null, null, null, 2); - - if (visible) { - header_type_member_declaration.append (finishfunc.copy ()); - } else { - finishfunc.modifiers |= CCodeModifiers.STATIC; - source_type_member_declaration.append (finishfunc.copy ()); + if (m.is_abstract || m.is_virtual) { + var vdecl = new CCodeDeclaration ("void"); + vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name + "_finish"); + vdecl.add_declarator (vdeclarator); + type_struct.add_declaration (vdecl); } + + generate_cparameters (m, creturn_type, false, cparam_map, finishfunc, vdeclarator, null, null, 2); + + if (!m.is_abstract) { + if (visible && m.base_method == null && m.base_interface_method == null) { + header_type_member_declaration.append (finishfunc.copy ()); + } else { + finishfunc.modifiers |= CCodeModifiers.STATIC; + source_type_member_declaration.append (finishfunc.copy ()); + } - finishfunc.block = finishblock; + finishfunc.block = finishblock; - source_type_member_definition.append (finishfunc); + source_type_member_definition.append (finishfunc); + } - // generate ready callback handler - var readyfunc = new CCodeFunction (m.get_cname () + "_ready", "void"); - readyfunc.line = function.line; + if (!m.is_abstract) { + // generate ready callback handler + var readyfunc = new CCodeFunction (m.get_cname () + "_ready", "void"); + readyfunc.line = function.line; - readyfunc.add_parameter (new CCodeFormalParameter ("source_object", "GObject*")); - readyfunc.add_parameter (new CCodeFormalParameter ("res", "GAsyncResult*")); - readyfunc.add_parameter (new CCodeFormalParameter ("user_data", "gpointer")); + readyfunc.add_parameter (new CCodeFormalParameter ("source_object", "GObject*")); + readyfunc.add_parameter (new CCodeFormalParameter ("res", "GAsyncResult*")); + readyfunc.add_parameter (new CCodeFormalParameter ("user_data", "gpointer")); - var readyblock = new CCodeBlock (); + var readyblock = new CCodeBlock (); - datadecl = new CCodeDeclaration (dataname + "*"); - datadecl.add_declarator (new CCodeVariableDeclarator ("data")); - readyblock.add_statement (datadecl); - readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), new CCodeIdentifier ("user_data")))); - readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "res"), new CCodeIdentifier ("res")))); + datadecl = new CCodeDeclaration (dataname + "*"); + datadecl.add_declarator (new CCodeVariableDeclarator ("data")); + readyblock.add_statement (datadecl); + readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), new CCodeIdentifier ("user_data")))); + readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "res"), new CCodeIdentifier ("res")))); - ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ())); - ccall.add_argument (new CCodeIdentifier ("data")); - readyblock.add_statement (new CCodeExpressionStatement (ccall)); + ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname () + "_co")); + ccall.add_argument (new CCodeIdentifier ("data")); + readyblock.add_statement (new CCodeExpressionStatement (ccall)); - readyfunc.modifiers |= CCodeModifiers.STATIC; - source_type_member_declaration.append (readyfunc.copy ()); + readyfunc.modifiers |= CCodeModifiers.STATIC; + source_type_member_declaration.append (readyfunc.copy ()); - readyfunc.block = readyblock; + readyfunc.block = readyblock; - source_type_member_definition.append (readyfunc); + source_type_member_definition.append (readyfunc); + } } public override void visit_yield_statement (YieldStatement stmt) { diff --git a/vala/valamethod.vala b/vala/valamethod.vala index 7f56cd802..96fb25d85 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -340,7 +340,7 @@ public class Vala.Method : Member { * @return the name to be used in C code */ public virtual string get_real_cname () { - if (base_method != null || base_interface_method != null || coroutine) { + if (base_method != null || base_interface_method != null) { return "%sreal_%s".printf (parent_symbol.get_lower_case_cprefix (), name); } else { return get_cname ();