]> git.lizzy.rs Git - rust.git/blob - src/rt/rust.cpp
03acdaa91e0381ba6a6304a56f7cdf3ff28b017c
[rust.git] / src / rt / rust.cpp
1 #include "rust_internal.h"
2 #include <cstdio>
3
4 struct
5 command_line_args : public kernel_owned<command_line_args>
6 {
7     rust_kernel *kernel;
8     rust_task *task;
9     int argc;
10     char **argv;
11
12     // [str] passed to rust_task::start.
13     rust_vec *args;
14
15     command_line_args(rust_task *task,
16                       int sys_argc,
17                       char **sys_argv)
18         : kernel(task->kernel),
19           task(task),
20           argc(sys_argc),
21           argv(sys_argv)
22     {
23 #if defined(__WIN32__)
24         LPCWSTR cmdline = GetCommandLineW();
25         LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc);
26         kernel->win32_require("CommandLineToArgvW", wargv != NULL);
27         argv = (char **) kernel->malloc(sizeof(char*) * argc,
28                                         "win32 command line");
29         for (int i = 0; i < argc; ++i) {
30             int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
31                                               NULL, 0, NULL, NULL);
32             kernel->win32_require("WideCharToMultiByte(0)", n_chars != 0);
33             argv[i] = (char *) kernel->malloc(n_chars,
34                                               "win32 command line arg");
35             n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
36                                           argv[i], n_chars, NULL, NULL);
37             kernel->win32_require("WideCharToMultiByte(1)", n_chars != 0);
38         }
39         LocalFree(wargv);
40 #endif
41
42         args = (rust_vec *)
43             kernel->malloc(vec_size<rust_vec*>(argc),
44                            "command line arg interior");
45         args->fill = args->alloc = sizeof(rust_vec*) * argc;
46         for (int i = 0; i < argc; ++i) {
47             rust_str *str = make_str(kernel, argv[i],
48                                      strlen(argv[i]),
49                                      "command line arg");
50             ((rust_str**)&args->data)[i] = str;
51         }
52     }
53
54     ~command_line_args() {
55         for (int i = 0; i < argc; ++i) {
56             rust_vec *s = ((rust_vec**)&args->data)[i];
57             kernel->free(s);
58         }
59         kernel->free(args);
60
61 #ifdef __WIN32__
62         for (int i = 0; i < argc; ++i) {
63             kernel->free(argv[i]);
64         }
65         kernel->free(argv);
66 #endif
67     }
68 };
69
70 /**
71  * Main entry point into the Rust runtime. Here we create a Rust service,
72  * initialize the kernel, create the root domain and run it.
73  */
74
75 int check_claims = 0;
76
77 extern "C" CDECL int
78 rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
79
80     rust_env *env = load_env();
81
82     update_log_settings(crate_map, env->logspec);
83     check_claims = env->check_claims;
84
85     rust_srv *srv = new rust_srv(env);
86     rust_kernel *kernel = new rust_kernel(srv, env->num_sched_threads);
87     rust_task_id root_id = kernel->create_task(NULL, "main");
88     rust_task *root_task = kernel->get_task_by_id(root_id);
89     I(kernel, root_task != NULL);
90     rust_scheduler *sched = root_task->sched;
91     command_line_args *args
92         = new (kernel, "main command line args")
93         command_line_args(root_task, argc, argv);
94
95     DLOG(sched, dom, "startup: %d args in 0x%" PRIxPTR,
96              args->argc, (uintptr_t)args->args);
97     for (int i = 0; i < args->argc; i++) {
98         DLOG(sched, dom, "startup: arg[%d] = '%s'", i, args->argv[i]);
99     }
100
101     root_task->start((spawn_fn)main_fn, NULL, args->args);
102     root_task->deref();
103     root_task = NULL;
104
105     int ret = kernel->start_task_threads();
106     delete args;
107     delete kernel;
108     delete srv;
109
110     free_env(env);
111
112     return ret;
113 }
114
115 //
116 // Local Variables:
117 // mode: C++
118 // fill-column: 78;
119 // indent-tabs-mode: nil
120 // c-basic-offset: 4
121 // buffer-file-coding-system: utf-8-unix
122 // End:
123 //