M gen/client.ha => gen/client.ha +3 -1
@@ 23,7 23,7 @@ const c_iface_method_src: str =
ep: helios::cap,$cparams$mparams
) $result = {
${caps_in_setup}const (tag, a1) = helios::call(ep,
- $iface_label::$methodid,$params
+ ($iface_label::$methodid << 16) | ($ncap << 8) | $nparam,$params
);
assert(rt::label(tag) == 0); // TODO: Error handling
return a1: $result;
@@ 112,6 112,8 @@ fn c_meth(
("method", meth.name),
("methodid", name),
("result", strio::string(&result)),
+ ("nparam", len(meth.params)),
+ ("ncap", len(meth.caps_in)),
("cparams", strio::string(&cparams)),
("caps_in_setup", strio::string(&caps_in_setup)),
("mparams", strio::string(&mparams)),
M gen/server.ha => gen/server.ha +30 -1
@@ 4,6 4,7 @@ use fmt;
use io;
use strio;
use tmpl = strings::template;
+use types;
// Generates code for a server to implement the given interface.
export fn server(out: io::handle, doc: *ast::document) (void | io::error) = {
@@ 157,7 158,8 @@ fn s_iface_object(
const s_iface_dispatch_header_src: str = `export fn $iface_dispatch(
object: *$iface,
) void = {
- const (tag, a1) = helios::recvraw(object._endpoint);
+ rt::ipcbuf.tag = ${max_cap} << 8;
+ const (tag, a1) = helios::recv(object._endpoint);
switch (rt::label(tag): $iface_label) {
`;
@@ 196,7 198,34 @@ fn s_iface_dispatch(
out: io::handle,
iface: *ast::interface,
) (void | io::error) = {
+ let setup = strio::dynamic();
+ defer io::close(&setup)!;
+
+ let maxcap = 0z;
+ for (let i = 0z; i < len(iface.methods); i += 1) {
+ const meth = &iface.methods[i];
+ if (len(meth.caps_in) > maxcap) {
+ maxcap = len(meth.caps_in);
+ };
+ for (let i = 0z; i < len(meth.caps_in); i += 1) {
+ const cap = meth.caps_in[i];
+ if (cap.variadic) {
+ maxcap = types::SIZE_MAX;
+ };
+ };
+ };
+
+ let max_cap = strio::dynamic();
+ defer io::close(&max_cap)!;
+
+ if (maxcap == types::SIZE_MAX) {
+ fmt::fprint(&max_cap, "rt::MAX_CAP")!;
+ } else {
+ fmt::fprint(&max_cap, maxcap)!;
+ };
+
tmpl::execute(&st_iface_dispatch_header, out,
+ ("max_cap", strio::string(&max_cap)),
("iface", iface.name),
)?;