From 265f2378176c53be3a192e105e9bc3af0d0e818d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 26 Nov 2022 11:17:45 +0100 Subject: [PATCH] server: implement return values --- ast/ast.ha | 2 +- ast/type.ha | 1 + gen/client.ha | 2 +- gen/server.ha | 31 +++++++++++++++++++++++++++++-- gen/shared.ha | 2 ++ lex/token.ha | 2 ++ parse/interface.ha | 4 ++-- parse/type.ha | 3 +++ 8 files changed, 41 insertions(+), 6 deletions(-) diff --git a/ast/ast.ha b/ast/ast.ha index 3924879..bdcd459 100644 --- a/ast/ast.ha +++ b/ast/ast.ha @@ -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. diff --git a/ast/type.ha b/ast/type.ha index 4efaba8..6cb59ed 100644 --- a/ast/type.ha +++ b/ast/type.ha @@ -12,6 +12,7 @@ export type ptype = enum { I64, SIZE, UINTPTR, + VOID, }; // An IPC type. diff --git a/gen/client.ha b/gen/client.ha index ab5f2e6..317b13a 100644 --- a/gen/client.ha +++ b/gen/client.ha @@ -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 )!; }; diff --git a/gen/server.ha b/gen/server.ha index 985acc4..317db26 100644 --- a/gen/server.ha +++ b/gen/server.ha @@ -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(¶ms)), - ("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(¶ms, ",")!; }; + 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(¶ms)), + ("rval_store", strio::string(&rval_store)), + ("rval_param", strio::string(&rval_param)), )?; }; diff --git a/gen/shared.ha b/gen/shared.ha index 2d3ff24..33dab76 100644 --- a/gen/shared.ha +++ b/gen/shared.ha @@ -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")?; }; diff --git a/lex/token.ha b/lex/token.ha index cd4aa37..b968758 100644 --- a/lex/token.ha +++ b/lex/token.ha @@ -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 => diff --git a/parse/interface.ha b/parse/interface.ha index 246f412..d77fd96 100644 --- a/parse/interface.ha +++ b/parse/interface.ha @@ -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; diff --git a/parse/type.ha b/parse/type.ha index 184db13..30928f2 100644 --- a/parse/type.ha +++ b/parse/type.ha @@ -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 => -- 2.45.2