Commit b7a06bd1 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

Various coroutine code generation improvements

2008-11-21  Jürg Billeter  <j@bitron.ch>

	* 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
parent 2dbbdb08
2008-11-21 Jürg Billeter <j@bitron.ch>
* 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 <j@bitron.ch>
* gobject/valaccodemethodmodule.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"));
}
}
}
......
......@@ -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<int,CCodeFormalParameter> (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<int,CCodeFormalParameter> (direct_hash, direct_equal);
var carg_map = new HashMap<int,CCodeExpression> (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<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? 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;
......
......@@ -52,9 +52,6 @@ public class Vala.DBusClientModule : DBusModule {
var cparam_map = new HashMap<int,CCodeFormalParameter> (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;
......
......@@ -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<int,CCodeFormalParameter> (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<int,CCodeFormalParameter> (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) {
......
......@@ -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 ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment