Lots of design changes around proxies and message passing. Made it so that domains can only talk to other domains via handles, and with the help of the rust_kernel.
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
#include "rust_internal.h"
|
||||
|
||||
struct
|
||||
command_line_args
|
||||
command_line_args : public dom_owned<command_line_args>
|
||||
{
|
||||
rust_dom &dom;
|
||||
rust_dom *dom;
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
// vec[str] passed to rust_task::start.
|
||||
rust_vec *args;
|
||||
|
||||
command_line_args(rust_dom &dom,
|
||||
command_line_args(rust_dom *dom,
|
||||
int sys_argc,
|
||||
char **sys_argv)
|
||||
: dom(dom),
|
||||
@@ -21,29 +21,29 @@ command_line_args
|
||||
#if defined(__WIN32__)
|
||||
LPCWSTR cmdline = GetCommandLineW();
|
||||
LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc);
|
||||
dom.win32_require("CommandLineToArgvW", wargv != NULL);
|
||||
argv = (char **) dom.malloc(sizeof(char*) * argc);
|
||||
dom->win32_require("CommandLineToArgvW", wargv != NULL);
|
||||
argv = (char **) dom->malloc(sizeof(char*) * argc);
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
dom.win32_require("WideCharToMultiByte(0)", n_chars != 0);
|
||||
argv[i] = (char *) dom.malloc(n_chars);
|
||||
dom->win32_require("WideCharToMultiByte(0)", n_chars != 0);
|
||||
argv[i] = (char *) dom->malloc(n_chars);
|
||||
n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
|
||||
argv[i], n_chars, NULL, NULL);
|
||||
dom.win32_require("WideCharToMultiByte(1)", n_chars != 0);
|
||||
dom->win32_require("WideCharToMultiByte(1)", n_chars != 0);
|
||||
}
|
||||
LocalFree(wargv);
|
||||
#endif
|
||||
size_t vec_fill = sizeof(rust_str *) * argc;
|
||||
size_t vec_alloc = next_power_of_two(sizeof(rust_vec) + vec_fill);
|
||||
void *mem = dom.malloc(vec_alloc);
|
||||
args = new (mem) rust_vec(&dom, vec_alloc, 0, NULL);
|
||||
void *mem = dom->malloc(vec_alloc);
|
||||
args = new (mem) rust_vec(dom, vec_alloc, 0, NULL);
|
||||
rust_str **strs = (rust_str**) &args->data[0];
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
size_t str_fill = strlen(argv[i]) + 1;
|
||||
size_t str_alloc = next_power_of_two(sizeof(rust_str) + str_fill);
|
||||
mem = dom.malloc(str_alloc);
|
||||
strs[i] = new (mem) rust_str(&dom, str_alloc, str_fill,
|
||||
mem = dom->malloc(str_alloc);
|
||||
strs[i] = new (mem) rust_str(dom, str_alloc, str_fill,
|
||||
(uint8_t const *)argv[i]);
|
||||
}
|
||||
args->fill = vec_fill;
|
||||
@@ -58,50 +58,55 @@ command_line_args
|
||||
// Drop the args we've had pinned here.
|
||||
rust_str **strs = (rust_str**) &args->data[0];
|
||||
for (int i = 0; i < argc; ++i)
|
||||
dom.free(strs[i]);
|
||||
dom.free(args);
|
||||
dom->free(strs[i]);
|
||||
dom->free(args);
|
||||
}
|
||||
|
||||
#ifdef __WIN32__
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
dom.free(argv[i]);
|
||||
dom->free(argv[i]);
|
||||
}
|
||||
dom.free(argv);
|
||||
dom->free(argv);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Main entry point into the Rust runtime. Here we create a Rust service,
|
||||
* initialize the kernel, create the root domain and run it.
|
||||
*/
|
||||
|
||||
extern "C" CDECL int
|
||||
rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
{
|
||||
rust_srv srv;
|
||||
rust_dom dom(&srv, crate, "main");
|
||||
srv.kernel->register_domain(&dom);
|
||||
command_line_args args(dom, argc, argv);
|
||||
rust_start(uintptr_t main_fn, rust_crate const *crate, int argc,
|
||||
char **argv) {
|
||||
|
||||
dom.log(rust_log::DOM, "startup: %d args", args.argc);
|
||||
for (int i = 0; i < args.argc; ++i)
|
||||
dom.log(rust_log::DOM,
|
||||
"startup: arg[%d] = '%s'", i, args.argv[i]);
|
||||
rust_srv *srv = new rust_srv();
|
||||
rust_kernel *kernel = new rust_kernel(srv);
|
||||
kernel->start();
|
||||
rust_handle<rust_dom> *handle = kernel->create_domain(crate, "main");
|
||||
rust_dom *dom = handle->referent();
|
||||
command_line_args *args = new (dom) command_line_args(dom, argc, argv);
|
||||
|
||||
if (dom._log.is_tracing(rust_log::DWARF)) {
|
||||
rust_crate_reader rdr(&dom, crate);
|
||||
}
|
||||
|
||||
uintptr_t main_args[4] = { 0, 0, 0, (uintptr_t)args.args };
|
||||
|
||||
dom.root_task->start(crate->get_exit_task_glue(),
|
||||
main_fn,
|
||||
(uintptr_t)&main_args,
|
||||
sizeof(main_args));
|
||||
|
||||
ret = dom.start_main_loop();
|
||||
srv.kernel->deregister_domain(&dom);
|
||||
dom->log(rust_log::DOM, "startup: %d args", args->argc);
|
||||
for (int i = 0; i < args->argc; i++) {
|
||||
dom->log(rust_log::DOM,
|
||||
"startup: arg[%d] = '%s'", i, args->argv[i]);
|
||||
}
|
||||
|
||||
if (dom->_log.is_tracing(rust_log::DWARF)) {
|
||||
rust_crate_reader create_reader(dom, crate);
|
||||
}
|
||||
|
||||
uintptr_t main_args[4] = {0, 0, 0, (uintptr_t)args->args};
|
||||
dom->root_task->start(crate->get_exit_task_glue(),
|
||||
main_fn, (uintptr_t)&main_args, sizeof(main_args));
|
||||
int ret = dom->start_main_loop();
|
||||
delete args;
|
||||
kernel->destroy_domain(dom);
|
||||
kernel->join_all_domains();
|
||||
delete kernel;
|
||||
delete srv;
|
||||
|
||||
#if !defined(__WIN32__)
|
||||
// Don't take down the process if the main thread exits without an
|
||||
// error.
|
||||
|
||||
Reference in New Issue
Block a user