vala r2225 - in trunk: . gobject
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r2225 - in trunk: . gobject
- Date: Fri, 19 Dec 2008 17:17:32 +0000 (UTC)
Author: juergbi
Date: Fri Dec 19 17:17:32 2008
New Revision: 2225
URL: http://svn.gnome.org/viewvc/vala?rev=2225&view=rev
Log:
2008-12-19 JÃrg Billeter <j bitron ch>
* gobject/valaccodebasemodule.vala:
* gobject/valaccodemethodcallmodule.vala:
Generate async and finish calls when calling async methods from
coroutines
Modified:
trunk/ChangeLog
trunk/gobject/valaccodebasemodule.vala
trunk/gobject/valaccodemethodcallmodule.vala
Modified: trunk/gobject/valaccodebasemodule.vala
==============================================================================
--- trunk/gobject/valaccodebasemodule.vala (original)
+++ trunk/gobject/valaccodebasemodule.vala Fri Dec 19 17:17:32 2008
@@ -69,7 +69,11 @@
public CCodeEnum cenum;
public CCodeFunction function;
public CCodeBlock block;
-
+
+ // code nodes to be inserted before the current statement
+ // used by async method calls in coroutines
+ public CCodeFragment pre_statement_fragment;
+
/* all temporary variables */
public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
/* temporary variables that own their content */
@@ -1479,6 +1483,11 @@
var cfrag = new CCodeFragment ();
+ if (pre_statement_fragment != null) {
+ cfrag.append (pre_statement_fragment);
+ pre_statement_fragment = null;
+ }
+
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (local.variable_type.get_cname (), get_variable_cname (local.name));
@@ -1937,25 +1946,6 @@
stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.expression.ccodenode);
- var invoc = stmt.expression as MethodCall;
- if (invoc != null) {
- var m = invoc.call.symbol_reference as Method;
- var ma = invoc.call as MemberAccess;
- if (m != null && m.coroutine && current_method != null && current_method.coroutine &&
- (ma == null || ma.member_name != "begin" || ma.inner.symbol_reference != ma.symbol_reference)) {
- var cfrag = new CCodeFragment ();
-
- int state = next_coroutine_state++;
-
- cfrag.append (stmt.ccodenode);
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state"), new CCodeConstant (state.to_string ()))));
- cfrag.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
- cfrag.append (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
-
- stmt.ccodenode = cfrag;
- }
- }
-
if (stmt.tree_can_fail && stmt.expression.tree_can_fail) {
// simple case, no node breakdown necessary
@@ -1977,7 +1967,12 @@
var cfrag = new CCodeFragment ();
append_temp_decl (cfrag, temp_vars);
-
+
+ if (pre_statement_fragment != null) {
+ cfrag.append (pre_statement_fragment);
+ pre_statement_fragment = null;
+ }
+
cfrag.append (stmt.ccodenode);
foreach (LocalVariable local in temp_ref_vars) {
Modified: trunk/gobject/valaccodemethodcallmodule.vala
==============================================================================
--- trunk/gobject/valaccodemethodcallmodule.vala (original)
+++ trunk/gobject/valaccodemethodcallmodule.vala Fri Dec 19 17:17:32 2008
@@ -35,6 +35,8 @@
// the bare function call
var ccall = new CCodeFunctionCall ((CCodeExpression) expr.call.ccodenode);
+ CCodeFunctionCall async_call = null;
+
Method m = null;
Gee.List<FormalParameter> params;
@@ -60,6 +62,32 @@
ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ()));
}
+ HashMap<int,CCodeExpression> in_arg_map, out_arg_map;
+
+ if (m != null && m.coroutine
+ && ((current_method != null && current_method.coroutine)
+ || (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference))) {
+ // async call
+
+ in_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+ out_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+
+ async_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname () + "_async"));
+
+ if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
+ // no finish call
+ ccall = async_call;
+ } else {
+ ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname () + "_finish"));
+
+ // pass GAsyncResult stored in closure to finish function
+ out_arg_map.set (get_param_pos (0.1), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "res"));
+ }
+ } else {
+ in_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+ out_arg_map = in_arg_map;
+ }
+
if (m is CreationMethod) {
ccall.add_argument (new CCodeIdentifier ("object_type"));
}
@@ -67,11 +95,9 @@
// the complete call expression, might include casts, comma expressions, and/or assignments
CCodeExpression ccall_expr = ccall;
- var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
-
if (m is ArrayResizeMethod) {
var array_type = (ArrayType) ma.inner.value_type;
- carg_map.set (get_param_pos (0), new CCodeIdentifier (array_type.element_type.get_cname ()));
+ in_arg_map.set (get_param_pos (0), new CCodeIdentifier (array_type.element_type.get_cname ()));
} else if (m is ArrayMoveMethod) {
requires_array_move = true;
}
@@ -103,7 +129,8 @@
}
}
- carg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
+ in_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
+ out_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
} else if (m != null && m.binding == MemberBinding.CLASS) {
var cl = (Class) m.parent_symbol;
var cast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null) + "_CLASS"));
@@ -127,14 +154,15 @@
}
cast.add_argument (klass);
- carg_map.set (get_param_pos (m.cinstance_parameter_position), cast);
+ in_arg_map.set (get_param_pos (m.cinstance_parameter_position), cast);
+ out_arg_map.set (get_param_pos (m.cinstance_parameter_position), cast);
}
if (m is ArrayMoveMethod) {
var array_type = (ArrayType) ma.inner.value_type;
var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
csizeof.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
- carg_map.set (get_param_pos (0.1), csizeof);
+ in_arg_map.set (get_param_pos (0.1), csizeof);
} else if (m is DynamicMethod) {
m.clear_parameters ();
int param_nr = 1;
@@ -171,6 +199,9 @@
Iterator<FormalParameter> params_it = params.iterator ();
foreach (Expression arg in expr.get_argument_list ()) {
CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
+
+ var carg_map = in_arg_map;
+
if (params_it.next ()) {
var param = params_it.get ();
ellipsis = param.params_array || param.ellipsis;
@@ -182,6 +213,10 @@
// http://bugzilla.gnome.org/show_bug.cgi?id=519597
bool multiple_cargs = false;
+ if (param.direction == ParameterDirection.OUT) {
+ carg_map = out_arg_map;
+ }
+
if (!param.no_array_length && param.parameter_type is ArrayType) {
var array_type = (ArrayType) param.parameter_type;
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -327,7 +362,7 @@
temp_vars.insert (0, temp_var);
- carg_map.set (get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+ out_arg_map.set (get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
expr.append_array_size (temp_ref);
} else {
@@ -343,7 +378,7 @@
temp_vars.insert (0, temp_var);
- carg_map.set (get_param_pos (m.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+ out_arg_map.set (get_param_pos (m.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
expr.delegate_target = temp_ref;
}
@@ -353,38 +388,37 @@
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"));
+ in_arg_map.set (get_param_pos (-1), new CCodeConstant ("NULL"));
+ in_arg_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"));
+ in_arg_map.set (get_param_pos (-1), new CCodeIdentifier (current_method.get_cname () + "_ready"));
+ in_arg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("data"));
}
}
}
if (m is CreationMethod && m.get_error_types ().size > 0) {
- carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
+ out_arg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
} else if (expr.tree_can_fail) {
// method can fail
current_method_inner_error = true;
// add &inner_error before the ellipsis arguments
- carg_map.set (get_param_pos (-1), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
+ out_arg_map.set (get_param_pos (-1), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
}
if (ellipsis) {
/* ensure variable argument list ends with NULL
* except when using printf-style arguments */
if (!m.printf_format && m.sentinel != "") {
- carg_map.set (get_param_pos (-1, true), new CCodeConstant (m.sentinel));
+ in_arg_map.set (get_param_pos (-1, true), new CCodeConstant (m.sentinel));
}
} else if (itype is DelegateType) {
var deleg_type = (DelegateType) itype;
var d = deleg_type.delegate_symbol;
if (d.has_target) {
- carg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
+ in_arg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
+ out_arg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
}
}
@@ -400,7 +434,7 @@
temp_vars.insert (0, temp_var);
- carg_map.set (get_param_pos (-1, true), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+ out_arg_map.set (get_param_pos (-1, true), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
var ccomma = new CCodeCommaExpression ();
ccomma.append_expression ((CCodeExpression) ccall_expr);
@@ -415,7 +449,7 @@
int min_pos;
while (true) {
min_pos = -1;
- foreach (int pos in carg_map.get_keys ()) {
+ foreach (int pos in out_arg_map.get_keys ()) {
if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
min_pos = pos;
}
@@ -423,16 +457,47 @@
if (min_pos == -1) {
break;
}
- ccall.add_argument (carg_map.get (min_pos));
+ ccall.add_argument (out_arg_map.get (min_pos));
last_pos = min_pos;
}
+ if (async_call != null) {
+ last_pos = -1;
+ while (true) {
+ min_pos = -1;
+ foreach (int pos in in_arg_map.get_keys ()) {
+ if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
+ min_pos = pos;
+ }
+ }
+ if (min_pos == -1) {
+ break;
+ }
+ async_call.add_argument (in_arg_map.get (min_pos));
+ last_pos = min_pos;
+ }
+ }
+
if (m != null && m.binding == MemberBinding.INSTANCE && m.returns_modified_pointer) {
expr.ccodenode = new CCodeAssignment (instance, ccall_expr);
} else {
expr.ccodenode = ccall_expr;
}
-
+
+ if (m != null && m.coroutine && current_method != null && current_method.coroutine) {
+ if (ma.member_name != "begin" || ma.inner.symbol_reference != ma.symbol_reference) {
+ if (pre_statement_fragment == null) {
+ pre_statement_fragment = new CCodeFragment ();
+ }
+ pre_statement_fragment.append (new CCodeExpressionStatement (async_call));
+
+ int state = next_coroutine_state++;
+ pre_statement_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state"), new CCodeConstant (state.to_string ()))));
+ pre_statement_fragment.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+ pre_statement_fragment.append (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
+ }
+ }
+
if (m is ArrayResizeMethod) {
// FIXME: size expression must not be evaluated twice at runtime (potential side effects)
Iterator<Expression> arg_it = expr.get_argument_list ().iterator ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]