diff --git a/include/ircd/cmds.h b/include/ircd/cmds.h index 15f248ed9..566e3212e 100644 --- a/include/ircd/cmds.h +++ b/include/ircd/cmds.h @@ -56,14 +56,8 @@ bool exists(const std::string &name); cmd *find(const std::string &name, const std::nothrow_t &); cmd &find(const std::string &name); -void execute(client &client, line); -void execute(client &client, const std::string &line); -void execute(client &client, const uint8_t *const &line, const size_t &len); -void execute(client &client, tape &); - } // namespace cmds -using cmds::execute; using cmds::cmd; } // namespace ircd diff --git a/include/ircd/stdinc.h b/include/ircd/stdinc.h index 9f34e7c4c..20038a0a5 100644 --- a/include/ircd/stdinc.h +++ b/include/ircd/stdinc.h @@ -90,6 +90,7 @@ namespace ircd #include "line.h" #include "tape.h" #include "cmds.h" +#include "vm.h" #include "u_id.h" diff --git a/include/ircd/vm.h b/include/ircd/vm.h new file mode 100644 index 000000000..bcc0b2bb0 --- /dev/null +++ b/include/ircd/vm.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 Charybdis Development Team + * Copyright (C) 2016 Jason Volk + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#define HAVE_IRCD_VM_H + +#ifdef __cplusplus +namespace ircd { +namespace vm { + +struct pool +{ + +}; + +void execute(client &client, line); +void execute(client &client, tape &); +void execute(client &client, const std::string &line); +void execute(client &client, const uint8_t *const &line, const size_t &len); + +} // namespace vm + +using vm::execute; + +} // namespace ircd +#endif diff --git a/ircd/Makefile.am b/ircd/Makefile.am index 5bfd5b14e..571f2eecc 100644 --- a/ircd/Makefile.am +++ b/ircd/Makefile.am @@ -43,7 +43,8 @@ libircd_la_SOURCES = \ info.cc \ cmds.cc \ ctx.cc \ - client.cc + client.cc \ + vm.cc #authproc.cc \ #bandbi.cc \ diff --git a/ircd/client.cc b/ircd/client.cc index 29e557e70..55f8716e8 100644 --- a/ircd/client.cc +++ b/ircd/client.cc @@ -259,9 +259,7 @@ try return; auto &rbuf(client.rbuf); - auto &reel(rbuf.reel); - execute(client, reel); - recv_next(client); + execute(client, rbuf.reel); } catch(const std::exception &e) { diff --git a/ircd/cmds.cc b/ircd/cmds.cc index ada2d2c08..fc0c4f328 100644 --- a/ircd/cmds.cc +++ b/ircd/cmds.cc @@ -65,43 +65,6 @@ ircd::cmds::cmd::emplace() log::info("Registered command \"%s\" to handler @ %p", name.c_str(), this); } -void -ircd::cmds::execute(client &client, - tape &reel) -{ - while(!reel.empty()) - { - execute(client, std::move(reel.front())); - reel.pop_front(); - } -} - -void -ircd::cmds::execute(client &client, - const uint8_t *const &ptr, - const size_t &len) -{ - execute(client, line(ptr, len)); -} - -void -ircd::cmds::execute(client &client, - const std::string &l) -{ - execute(client, line(l)); -} - -void -ircd::cmds::execute(client &client, - line line) -{ - if(line.empty()) - return; - - auto &handle(find(command(line))); - handle(client, std::move(line)); -} - ircd::cmds::cmd & ircd::cmds::find(const std::string &name) try diff --git a/ircd/vm.cc b/ircd/vm.cc new file mode 100644 index 000000000..fe5cabca8 --- /dev/null +++ b/ircd/vm.cc @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2016 Charybdis Development Team + * Copyright (C) 2016 Jason Volk + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +namespace ircd { + + +} // namespace ircd + +void +ircd::vm::execute(client &client, + const uint8_t *const &ptr, + const size_t &len) +{ + execute(client, line(ptr, len)); +} + +void +ircd::vm::execute(client &client, + const std::string &l) +{ + execute(client, line(l)); +} + +void +ircd::vm::execute(client &client, + tape &reel) +{ + context([wp(weak_from(client)), &client, &reel] + { + auto cp(wp.lock()); // Hold the client for the lifetime of this context + + if(!cp) // client already gone though + return; + + while(!reel.empty()) try + { + auto &line(reel.front()); + const scope pop([&reel] + { + reel.pop_front(); + }); + + if(line.empty()) + continue; + + auto &handle(cmds::find(command(line))); + handle(client, std::move(line)); + } + catch(const std::exception &e) + { + log::error("vm: %s", e.what()); + disconnect(client); + finished(client); + return; + } + + recv_next(client); + }, + ctx::SELF_DESTRUCT); +} + +void +ircd::vm::execute(client &client, + line line) +{ + if(line.empty()) + return; + + auto &handle(cmds::find(command(line))); + handle(client, std::move(line)); +}