~sircmpwn/ipcgen

29f708b066e7a781ae616ed4a9c5e5f01af4fcd9 — Drew DeVault a month ago a4ca97d
Use lower-level IPC call setup
2 files changed, 33 insertions(+), 2 deletions(-)

M gen/client.ha
M gen/server.ha
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),
	)?;