@@ -7,19 +7,18 @@ command_line_args : public kernel_owned<command_line_args>
7
7
rust_task *task;
8
8
int argc;
9
9
char **argv;
10
+ rust_str **strs;
10
11
11
- // vec[str] passed to rust_task::start.
12
- rust_vec *args;
13
- rust_ivec *args_ivec;
12
+ // [str] passed to rust_task::start.
13
+ rust_ivec *args;
14
14
15
15
command_line_args (rust_task *task,
16
16
int sys_argc,
17
17
char **sys_argv)
18
18
: kernel(task->kernel),
19
19
task (task),
20
20
argc(sys_argc),
21
- argv(sys_argv),
22
- args(NULL )
21
+ argv(sys_argv)
23
22
{
24
23
#if defined(__WIN32__)
25
24
LPCWSTR cmdline = GetCommandLineW ();
@@ -40,10 +39,9 @@ command_line_args : public kernel_owned<command_line_args>
40
39
LocalFree (wargv);
41
40
#endif
42
41
size_t vec_fill = sizeof (rust_str *) * argc;
43
- size_t vec_alloc = next_power_of_two (sizeof (rust_vec) + vec_fill);
42
+ size_t vec_alloc = next_power_of_two (vec_fill);
44
43
void *mem = kernel->malloc (vec_alloc, " command line" );
45
- args = new (mem) rust_vec (vec_alloc, 0 , NULL );
46
- rust_str **strs = (rust_str**) &args->data [0 ];
44
+ strs = (rust_str**) mem;
47
45
for (int i = 0 ; i < argc; ++i) {
48
46
size_t str_fill = strlen (argv[i]) + 1 ;
49
47
size_t str_alloc = next_power_of_two (sizeof (rust_str) + str_fill);
@@ -52,38 +50,29 @@ command_line_args : public kernel_owned<command_line_args>
52
50
(uint8_t const *)argv[i]);
53
51
strs[i]->ref_count ++;
54
52
}
55
- args->fill = vec_fill;
56
- // If the caller has a declared args array, they may drop; but
57
- // we don't know if they have such an array. So we pin the args
58
- // array here to ensure it survives to program-shutdown.
59
- args->ref ();
60
53
61
54
size_t ivec_interior_sz =
62
55
sizeof (size_t ) * 2 + sizeof (rust_str *) * 4 ;
63
- args_ivec = (rust_ivec *)
56
+ args = (rust_ivec *)
64
57
kernel->malloc (ivec_interior_sz,
65
58
" command line arg interior" );
66
- args_ivec ->fill = 0 ;
59
+ args ->fill = 0 ;
67
60
size_t ivec_exterior_sz = sizeof (rust_str *) * argc;
68
- args_ivec ->alloc = ivec_exterior_sz;
69
- // NB: This is freed by some ivec machinery, probably the drop
70
- // glue in main, so we don't free it ourselves
71
- args_ivec ->payload .ptr = (rust_ivec_heap *)
61
+ args ->alloc = ivec_exterior_sz;
62
+ // NB: _rust_main owns the ivec payload and will be responsible for
63
+ // freeing it
64
+ args ->payload .ptr = (rust_ivec_heap *)
72
65
kernel->malloc (ivec_exterior_sz + sizeof (size_t ),
73
66
" command line arg exterior" );
74
- args_ivec ->payload .ptr ->fill = ivec_exterior_sz;
75
- memcpy (&args_ivec ->payload .ptr ->data , strs, ivec_exterior_sz);
67
+ args ->payload .ptr ->fill = ivec_exterior_sz;
68
+ memcpy (&args ->payload .ptr ->data , strs, ivec_exterior_sz);
76
69
}
77
70
78
71
~command_line_args () {
79
- kernel->free (args_ivec);
80
- if (args) {
81
- // Drop the args we've had pinned here.
82
- rust_str **strs = (rust_str**) &args->data [0 ];
83
- for (int i = 0 ; i < argc; ++i)
84
- kernel->free (strs[i]);
85
- kernel->free (args);
86
- }
72
+ kernel->free (args);
73
+ for (int i = 0 ; i < argc; ++i)
74
+ kernel->free (strs[i]);
75
+ kernel->free (strs);
87
76
88
77
#ifdef __WIN32__
89
78
for (int i = 0 ; i < argc; ++i) {
@@ -127,7 +116,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv,
127
116
DLOG (sched, dom, " startup: arg[%d] = '%s'" , i, args->argv [i]);
128
117
}
129
118
130
- root_task->start (main_fn, (uintptr_t )args->args_ivec );
119
+ root_task->start (main_fn, (uintptr_t )args->args );
131
120
root_task->deref ();
132
121
root_task = NULL ;
133
122
0 commit comments