Skip to content

Commit

Permalink
codegen: Fix support of dynamic DBus methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ricotz committed Nov 15, 2019
1 parent e9f78ba commit ab6fbac
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
7 changes: 7 additions & 0 deletions codegen/valaccodemethodcallmodule.vala
Expand Up @@ -296,6 +296,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
csizeof.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
in_arg_map.set (get_param_pos (0.1), csizeof);
} else if (m is DynamicMethod) {
emit_context.push_symbol (m);
m.clear_parameters ();
int param_nr = 1;
foreach (Expression arg in expr.get_argument_list ()) {
Expand All @@ -320,6 +321,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
param.accept (this);
}
generate_dynamic_method_wrapper ((DynamicMethod) m);
emit_context.pop_symbol ();
} else if (m is CreationMethod && context.profile == Profile.GOBJECT && m.parent_symbol is Class) {
ccode.add_assignment (get_this_cexpression (), new CCodeCastExpression (ccall, get_ccode_name (current_class) + "*"));

Expand Down Expand Up @@ -873,6 +875,11 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
ccode.add_expression (destroy_value (unary.inner.target_value));
}

// infer type of out-parameter from argument
if (ma.symbol_reference is DynamicMethod && unary.target_value.value_type == null) {
unary.target_value.value_type = unary.inner.value_type.copy ();
}

// assign new value
store_value (unary.inner.target_value, transform_value (unary.target_value, unary.inner.value_type, arg), expr.source_reference);

Expand Down
6 changes: 2 additions & 4 deletions codegen/valagdbusclientmodule.vala
Expand Up @@ -43,8 +43,6 @@ public class Vala.GDBusClientModule : GDBusModule {
}

public override void generate_dynamic_method_wrapper (DynamicMethod method) {
var dynamic_method = (DynamicMethod) method;

var func = new CCodeFunction (get_ccode_name (method));
func.modifiers = CCodeModifiers.STATIC;

Expand All @@ -54,10 +52,10 @@ public class Vala.GDBusClientModule : GDBusModule {

push_function (func);

if (dynamic_method.dynamic_type.data_type == dbus_proxy_type) {
if (method.dynamic_type.data_type == dbus_proxy_type) {
generate_marshalling (method, CallType.SYNC, null, method.name, -1);
} else {
Report.error (method.source_reference, "dynamic methods are not supported for `%s'".printf (dynamic_method.dynamic_type.to_string ()));
Report.error (method.source_reference, "dynamic methods are not supported for `%s'".printf (method.dynamic_type.to_string ()));
}

pop_function ();
Expand Down
1 change: 1 addition & 0 deletions tests/Makefile.am
Expand Up @@ -510,6 +510,7 @@ TESTS = \
dbus/errors.test \
dbus/async.test \
dbus/async-errors.test \
dbus/dynamic-method.test \
dbus/enum-string-marshalling.vala \
dbus/signals.test \
dbus/filedescriptor.test \
Expand Down
63 changes: 63 additions & 0 deletions tests/dbus/dynamic-method.test
@@ -0,0 +1,63 @@
Packages: gio-2.0
D-Bus

Program: client

async void run () {
try {
var bus = yield Bus.@get (BusType.SESSION);
dynamic DBusProxy test = yield new DBusProxy (bus, DBusProxyFlags.NONE, null, bus.get_unique_name (), "/org/example/test", "org.example.Test");
string s;
int i = test.do_foo (42, out s);
assert (i == 23);
assert (s == "foo");
} catch {
}

main_loop.quit ();
}

MainLoop main_loop;

void main () {
main_loop = new MainLoop ();
run.begin ();
main_loop.run ();
}

Program: server

[DBus (name = "org.example.Test")]
class Test : Object {
public int do_foo (int i, out string s) throws Error {
assert (i == 42);
s = "foo";
return 23;
}
}

MainLoop main_loop;

void client_exit (Pid pid, int status) {
// client finished, terminate server
assert (status == 0);
main_loop.quit ();
}

void main () {
var conn = Bus.get_sync (BusType.SESSION);
conn.register_object ("/org/example/test", new Test ());

// try to register service in session bus
var request_result = conn.call_sync ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RequestName",
new Variant ("(su)", "org.example.Test", 0x4), null, 0, -1);
assert ((uint) request_result.get_child_value (0) == 1);

// server ready, spawn client
Pid client_pid;
Process.spawn_async (null, { "dbus_dynamic_method_client" }, null, SpawnFlags.DO_NOT_REAP_CHILD, null, out client_pid);
ChildWatch.add (client_pid, client_exit);

main_loop = new MainLoop ();
main_loop.run ();
}
1 change: 1 addition & 0 deletions vala/valamemberaccess.vala
Expand Up @@ -398,6 +398,7 @@ public class Vala.MemberAccess : Expression {
m.add_error_type (err);
m.access = SymbolAccessibility.PUBLIC;
m.add_parameter (new Parameter.with_ellipsis ());
m.this_parameter = new Parameter ("this", dynamic_object_type.copy ());
dynamic_object_type.type_symbol.scope.add (null, m);
symbol_reference = m;
}
Expand Down

0 comments on commit ab6fbac

Please sign in to comment.