~sircmpwn/ipcgen

265f2378176c53be3a192e105e9bc3af0d0e818d — Drew DeVault 1 year, 3 months ago 554996b
server: implement return values
8 files changed, 41 insertions(+), 6 deletions(-)

M ast/ast.ha
M ast/type.ha
M gen/client.ha
M gen/server.ha
M gen/shared.ha
M lex/token.ha
M parse/interface.ha
M parse/type.ha
M ast/ast.ha => ast/ast.ha +1 -1
@@ 20,7 20,7 @@ export type method = struct {
	caps_in: []capability,
	caps_out: []capability,
	params: []param,
	//result: result_type,
	result: ipc_type,
};

// The ABI type of a method.

M ast/type.ha => ast/type.ha +1 -0
@@ 12,6 12,7 @@ export type ptype = enum {
	I64,
	SIZE,
	UINTPTR,
	VOID,
};

// An IPC type.

M gen/client.ha => gen/client.ha +1 -1
@@ 21,7 21,7 @@ const c_iface_method_src: str =
	`export fn $iface_$method(
	ep: helios::cap,$mparams
) $result = {
	helios::send(ep,
	helios::call(ep,
		$iface_label::$methodid,$params
	)!;
};

M gen/server.ha => gen/server.ha +29 -2
@@ 1,4 1,5 @@
use ast;
use ast::{ptype};
use fmt;
use io;
use strio;


@@ 109,12 110,16 @@ fn s_method_fntype(
		};
	};

	let result = strio::dynamic();
	defer io::close(&result)!;
	ipc_type(&result, &meth.result)!;

	tmpl::execute(&st_method_fntype, out,
		("method", meth.name),
		("iface", iface.name),
		("object", iface.name),
		("params", strio::string(&params)),
		("result", "void"), // TODO
		("result", strio::string(&result)),
	)?;
	fmt::fprintln(out)?;
};


@@ 151,10 156,21 @@ const s_iface_dispatch_footer_src: str = `	case =>
	};
};
`;

// XXX: It might be nice if we didn't have to do a reply syscall to detect that
// the user stored the reply capability for later
const s_iface_dispatch_method_src: str = `	case $iface_label::$methodid =>
		object._iface.$method(
		${rval_store}object._iface.$method(
			object,$params
		);
		match (helios::reply(0${rval_param})) {
		case void =>
			yield;
		case errors::invalid_cslot =>
			yield; // callee stored the reply
		case errors::error =>
			abort(); // TODO
		};
`;
let st_iface_dispatch_header: tmpl::template = [];
let st_iface_dispatch_footer: tmpl::template = [];


@@ 207,10 223,21 @@ fn s_method_dispatch(
		fmt::fprint(&params, ",")!;
	};

	let rval_store = strio::dynamic();
	defer io::close(&rval_store)!;
	let rval_param = strio::dynamic();
	defer io::close(&rval_param)!;
	if (!(meth.result is ptype) || meth.result as ptype != ptype::VOID) {
		fmt::fprintf(&rval_store, "const rval = ")!;
		fmt::fprintf(&rval_param, ", rval")!;
	};

	tmpl::execute(&st_iface_dispatch_method, out,
		("iface", iface.name),
		("method", meth.name),
		("methodid", method_id),
		("params", strio::string(&params)),
		("rval_store", strio::string(&rval_store)),
		("rval_param", strio::string(&rval_param)),
	)?;
};

M gen/shared.ha => gen/shared.ha +2 -0
@@ 61,6 61,8 @@ fn ipc_type(
			fmt::fprint(out, "i64")?;
		case ast::ptype::SIZE =>
			fmt::fprint(out, "size")?;
		case ast::ptype::VOID =>
			fmt::fprint(out, "void")?;
		case ast::ptype::UINTPTR =>
			fmt::fprint(out, "uintptr")?;
		};

M lex/token.ha => lex/token.ha +2 -0
@@ 92,6 92,8 @@ export fn ltokstr(tok: ltok) const str = {
		return "namespace";
	case ltok::UINT =>
		return "uint";
	case ltok::INT =>
		return "int";
	case ltok::I8 =>
		return "i8";
	case ltok::I16 =>

M parse/interface.ha => parse/interface.ha +2 -2
@@ 71,6 71,7 @@ fn method(lex: *lex::lexer) (ast::method | error) = {
		const name = strings::dup(want(lex, ltok::WORD)?.1 as str);
		want(lex, ltok::COLON)?;
		const ptype = ipc_type(lex)?;
		// TODO: Prevent void from being used in parameters

		append(meth.params, ast::param {
			name = name,


@@ 87,8 88,7 @@ fn method(lex: *lex::lexer) (ast::method | error) = {
		};
	};

	// TODO: Parse result type properly
	want(lex, ltok::VOID)?;
	meth.result = ipc_type(lex)?;

	want(lex, ltok::SEMICOLON)?;
	return meth;

M parse/type.ha => parse/type.ha +3 -0
@@ 16,6 16,7 @@ fn ipc_type(lex: *lex::lexer) (ast::ipc_type | error) = {
		ltok::I64,
		ltok::SIZE,
		ltok::UINTPTR,
		ltok::VOID,
		ltok::WORD,
	)?;
	switch (tok.0) {


@@ 41,6 42,8 @@ fn ipc_type(lex: *lex::lexer) (ast::ipc_type | error) = {
		return ast::ptype::I64;
	case ltok::SIZE =>
		return ast::ptype::SIZE;
	case ltok::VOID =>
		return ast::ptype::VOID;
	case ltok::UINTPTR =>
		return ast::ptype::UINTPTR;
	case ltok::WORD =>