6
6
#include " rust_upcall.h"
7
7
#include < stdint.h>
8
8
9
+ #define SWITCH_STACK (A, F ) upcall_call_shim_on_c_stack((void *)A, (void *)F)
10
+
9
11
extern " C" void record_sp (void *limit);
10
12
11
13
/* *
@@ -32,26 +34,6 @@ upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
32
34
task->record_stack_limit ();
33
35
}
34
36
35
- #if defined(__i386__) || defined(__x86_64__) || defined(_M_X64)
36
- void
37
- check_stack (rust_task *task) {
38
- void *esp;
39
- # ifdef __i386__
40
- asm volatile (" movl %%esp,%0" : " =r" (esp));
41
- # else
42
- asm volatile (" mov %%rsp,%0" : " =r" (esp));
43
- # endif
44
- if (esp < task->stk ->data )
45
- task->kernel ->fatal (" Out of stack space, sorry" );
46
- }
47
- #else
48
- #warning "Stack checks are not supported on this architecture"
49
- void
50
- check_stack (rust_task *task) {
51
- // TODO
52
- }
53
- #endif
54
-
55
37
// Copy elements from one vector to another,
56
38
// dealing with reference counts
57
39
static inline void
@@ -87,11 +69,12 @@ upcall_s_fail(s_fail_args *args) {
87
69
}
88
70
89
71
struct s_malloc_args {
72
+ uintptr_t retval;
90
73
size_t nbytes;
91
74
type_desc *td;
92
75
};
93
76
94
- extern " C" CDECL uintptr_t
77
+ extern " C" CDECL void
95
78
upcall_s_malloc (s_malloc_args *args) {
96
79
rust_task *task = rust_scheduler::get_task ();
97
80
LOG_UPCALL_ENTRY (task);
@@ -115,7 +98,7 @@ upcall_s_malloc(s_malloc_args *args) {
115
98
LOG (task, mem,
116
99
" upcall malloc(%" PRIdPTR " , 0x%" PRIxPTR " ) = 0x%" PRIxPTR,
117
100
args->nbytes , args->td , (uintptr_t )p);
118
- return (uintptr_t ) p;
101
+ args-> retval = (uintptr_t ) p;
119
102
}
120
103
121
104
struct s_free_args {
@@ -143,11 +126,12 @@ upcall_s_free(s_free_args *args) {
143
126
}
144
127
145
128
struct s_shared_malloc_args {
129
+ uintptr_t retval;
146
130
size_t nbytes;
147
131
type_desc *td;
148
132
};
149
133
150
- extern " C" CDECL uintptr_t
134
+ extern " C" CDECL void
151
135
upcall_s_shared_malloc (s_shared_malloc_args *args) {
152
136
rust_task *task = rust_scheduler::get_task ();
153
137
LOG_UPCALL_ENTRY (task);
@@ -161,7 +145,7 @@ upcall_s_shared_malloc(s_shared_malloc_args *args) {
161
145
" upcall shared_malloc(%" PRIdPTR " , 0x%" PRIxPTR
162
146
" ) = 0x%" PRIxPTR,
163
147
args->nbytes , args->td , (uintptr_t )p);
164
- return (uintptr_t ) p;
148
+ args-> retval = (uintptr_t ) p;
165
149
}
166
150
167
151
struct s_shared_free_args {
@@ -184,17 +168,17 @@ upcall_s_shared_free(s_shared_free_args *args) {
184
168
}
185
169
186
170
struct s_get_type_desc_args {
171
+ type_desc *retval;
187
172
size_t size;
188
173
size_t align;
189
174
size_t n_descs;
190
175
type_desc const **descs;
191
176
uintptr_t n_obj_params;
192
177
};
193
178
194
- extern " C" CDECL type_desc *
179
+ extern " C" CDECL void
195
180
upcall_s_get_type_desc (s_get_type_desc_args *args) {
196
181
rust_task *task = rust_scheduler::get_task ();
197
- check_stack (task);
198
182
LOG_UPCALL_ENTRY (task);
199
183
200
184
LOG (task, cache, " upcall get_type_desc with size=%" PRIdPTR
@@ -204,7 +188,7 @@ upcall_s_get_type_desc(s_get_type_desc_args *args) {
204
188
type_desc *td = cache->get_type_desc (args->size , args->align , args->n_descs ,
205
189
args->descs , args->n_obj_params );
206
190
LOG (task, cache, " returning tydesc 0x%" PRIxPTR, td);
207
- return td;
191
+ args-> retval = td;
208
192
}
209
193
210
194
struct s_vec_grow_args {
@@ -238,16 +222,21 @@ upcall_s_vec_push(s_vec_push_args *args) {
238
222
v->fill += args->elt_ty ->size ;
239
223
}
240
224
225
+ struct s_dynastack_mark_args {
226
+ void *retval;
227
+ };
228
+
241
229
/* *
242
230
* Returns a token that can be used to deallocate all of the allocated space
243
231
* space in the dynamic stack.
244
232
*/
245
- extern " C" CDECL void *
246
- upcall_s_dynastack_mark () {
247
- return rust_scheduler::get_task ()->dynastack .mark ();
233
+ extern " C" CDECL void
234
+ upcall_s_dynastack_mark (s_dynastack_mark_args *args ) {
235
+ args-> retval = rust_scheduler::get_task ()->dynastack .mark ();
248
236
}
249
237
250
238
struct s_dynastack_alloc_args {
239
+ void *retval;
251
240
size_t sz;
252
241
};
253
242
@@ -256,13 +245,15 @@ struct s_dynastack_alloc_args {
256
245
*
257
246
* FIXME: Deprecated since dynamic stacks need to be self-describing for GC.
258
247
*/
259
- extern " C" CDECL void *
248
+ extern " C" CDECL void
260
249
upcall_s_dynastack_alloc (s_dynastack_alloc_args *args) {
261
250
size_t sz = args->sz ;
262
- return sz ? rust_scheduler::get_task ()->dynastack .alloc (sz, NULL ) : NULL ;
251
+ args->retval = sz ?
252
+ rust_scheduler::get_task ()->dynastack .alloc (sz, NULL ) : NULL ;
263
253
}
264
254
265
255
struct s_dynastack_alloc_2_args {
256
+ void *retval;
266
257
size_t sz;
267
258
type_desc *ty;
268
259
};
@@ -271,11 +262,12 @@ struct s_dynastack_alloc_2_args {
271
262
* Allocates space associated with a type descriptor in the dynamic stack and
272
263
* returns it.
273
264
*/
274
- extern " C" CDECL void *
265
+ extern " C" CDECL void
275
266
upcall_s_dynastack_alloc_2 (s_dynastack_alloc_2_args *args) {
276
267
size_t sz = args->sz ;
277
268
type_desc *ty = args->ty ;
278
- return sz ? rust_scheduler::get_task ()->dynastack .alloc (sz, ty) : NULL ;
269
+ args->retval = sz ?
270
+ rust_scheduler::get_task ()->dynastack .alloc (sz, ty) : NULL ;
279
271
}
280
272
281
273
struct s_dynastack_free_args {
@@ -296,20 +288,21 @@ __gxx_personality_v0(int version,
296
288
_Unwind_Context *context);
297
289
298
290
struct s_rust_personality_args {
291
+ _Unwind_Reason_Code retval;
299
292
int version;
300
293
_Unwind_Action actions;
301
294
uint64_t exception_class;
302
295
_Unwind_Exception *ue_header;
303
296
_Unwind_Context *context;
304
297
};
305
298
306
- extern " C" _Unwind_Reason_Code
299
+ extern " C" void
307
300
upcall_s_rust_personality (s_rust_personality_args *args) {
308
- return __gxx_personality_v0 (args->version ,
309
- args->actions ,
310
- args->exception_class ,
311
- args->ue_header ,
312
- args->context );
301
+ args-> retval = __gxx_personality_v0 (args->version ,
302
+ args->actions ,
303
+ args->exception_class ,
304
+ args->ue_header ,
305
+ args->context );
313
306
}
314
307
315
308
extern " C" void
@@ -355,14 +348,17 @@ extern "C" CDECL void
355
348
upcall_fail (char const *expr,
356
349
char const *file,
357
350
size_t line) {
351
+ // FIXME: Need to fix the stack switching function to unwind properly
352
+ // in order to switch stacks here
358
353
s_fail_args args = {expr,file,line};
359
354
upcall_s_fail (&args);
360
355
}
361
356
362
357
extern " C" CDECL uintptr_t
363
358
upcall_malloc (size_t nbytes, type_desc *td) {
364
- s_malloc_args args = {nbytes, td};
365
- return upcall_s_malloc (&args);
359
+ s_malloc_args args = {0 , nbytes, td};
360
+ SWITCH_STACK (&args, upcall_s_malloc);
361
+ return args.retval ;
366
362
}
367
363
368
364
/* *
@@ -371,13 +367,14 @@ upcall_malloc(size_t nbytes, type_desc *td) {
371
367
extern " C" CDECL void
372
368
upcall_free (void * ptr, uintptr_t is_gc) {
373
369
s_free_args args = {ptr, is_gc};
374
- upcall_s_free (&args);
370
+ SWITCH_STACK (&args, upcall_s_free );
375
371
}
376
372
377
373
extern " C" CDECL uintptr_t
378
374
upcall_shared_malloc (size_t nbytes, type_desc *td) {
379
- s_shared_malloc_args args = {nbytes, td};
380
- return upcall_s_shared_malloc (&args);
375
+ s_shared_malloc_args args = {0 , nbytes, td};
376
+ SWITCH_STACK (&args, upcall_s_shared_malloc);
377
+ return args.retval ;
381
378
}
382
379
383
380
/* *
@@ -386,7 +383,7 @@ upcall_shared_malloc(size_t nbytes, type_desc *td) {
386
383
extern " C" CDECL void
387
384
upcall_shared_free (void * ptr) {
388
385
s_shared_free_args args = {ptr};
389
- upcall_s_shared_free (&args);
386
+ SWITCH_STACK (&args, upcall_s_shared_free );
390
387
}
391
388
392
389
extern " C" CDECL type_desc *
@@ -396,18 +393,21 @@ upcall_get_type_desc(void *curr_crate, // ignored, legacy compat.
396
393
size_t n_descs,
397
394
type_desc const **descs,
398
395
uintptr_t n_obj_params) {
399
- s_get_type_desc_args args = {size,align,n_descs,descs,n_obj_params};
400
- return upcall_s_get_type_desc (&args);
396
+ s_get_type_desc_args args = {0 ,size,align,n_descs,descs,n_obj_params};
397
+ SWITCH_STACK (&args, upcall_s_get_type_desc);
398
+ return args.retval ;
401
399
}
402
400
403
401
extern " C" CDECL void
404
402
upcall_vec_grow (rust_vec** vp, size_t new_sz) {
405
403
s_vec_grow_args args = {vp, new_sz};
406
- upcall_s_vec_grow (&args);
404
+ SWITCH_STACK (&args, upcall_s_vec_grow );
407
405
}
408
406
409
407
extern " C" CDECL void
410
408
upcall_vec_push (rust_vec** vp, type_desc* elt_ty, void * elt) {
409
+ // FIXME: Switching stacks here causes crashes, probably
410
+ // because this upcall calls take glue
411
411
s_vec_push_args args = {vp, elt_ty, elt};
412
412
upcall_s_vec_push (&args);
413
413
}
@@ -418,7 +418,9 @@ upcall_vec_push(rust_vec** vp, type_desc* elt_ty, void* elt) {
418
418
*/
419
419
extern " C" CDECL void *
420
420
upcall_dynastack_mark () {
421
- return upcall_s_dynastack_mark ();
421
+ s_dynastack_mark_args args = {0 };
422
+ SWITCH_STACK (&args, upcall_s_dynastack_mark);
423
+ return args.retval ;
422
424
}
423
425
424
426
/* *
@@ -428,8 +430,9 @@ upcall_dynastack_mark() {
428
430
*/
429
431
extern " C" CDECL void *
430
432
upcall_dynastack_alloc (size_t sz) {
431
- s_dynastack_alloc_args args = {sz};
432
- return upcall_s_dynastack_alloc (&args);
433
+ s_dynastack_alloc_args args = {0 , sz};
434
+ SWITCH_STACK (&args, upcall_s_dynastack_alloc);
435
+ return args.retval ;
433
436
}
434
437
435
438
/* *
@@ -438,15 +441,16 @@ upcall_dynastack_alloc(size_t sz) {
438
441
*/
439
442
extern " C" CDECL void *
440
443
upcall_dynastack_alloc_2 (size_t sz, type_desc *ty) {
441
- s_dynastack_alloc_2_args args = {sz, ty};
442
- return upcall_s_dynastack_alloc_2 (&args);
444
+ s_dynastack_alloc_2_args args = {0 , sz, ty};
445
+ SWITCH_STACK (&args, upcall_s_dynastack_alloc_2);
446
+ return args.retval ;
443
447
}
444
448
445
449
/* * Frees space in the dynamic stack. */
446
450
extern " C" CDECL void
447
451
upcall_dynastack_free (void *ptr) {
448
452
s_dynastack_free_args args = {ptr};
449
- return upcall_s_dynastack_free (&args);
453
+ SWITCH_STACK (&args, upcall_s_dynastack_free );
450
454
}
451
455
452
456
extern " C" _Unwind_Reason_Code
@@ -455,23 +459,25 @@ upcall_rust_personality(int version,
455
459
uint64_t exception_class,
456
460
_Unwind_Exception *ue_header,
457
461
_Unwind_Context *context) {
458
- s_rust_personality_args args = {version, actions, exception_class, ue_header,
459
- context};
460
- return upcall_s_rust_personality (&args);
462
+ s_rust_personality_args args = {(_Unwind_Reason_Code)0 ,
463
+ version, actions, exception_class,
464
+ ue_header, context};
465
+ SWITCH_STACK (&args, upcall_s_rust_personality);
466
+ return args.retval ;
461
467
}
462
468
463
469
extern " C" void
464
470
upcall_cmp_type (int8_t *result, const type_desc *tydesc,
465
471
const type_desc **subtydescs, uint8_t *data_0,
466
472
uint8_t *data_1, uint8_t cmp_type) {
467
473
s_cmp_type_args args = {result, tydesc, subtydescs, data_0, data_1, cmp_type};
468
- upcall_s_cmp_type (&args);
474
+ SWITCH_STACK (&args, upcall_s_cmp_type );
469
475
}
470
476
471
477
extern " C" void
472
478
upcall_log_type (const type_desc *tydesc, uint8_t *data, uint32_t level) {
473
479
s_log_type_args args = {tydesc, data, level};
474
- upcall_s_log_type (&args);
480
+ SWITCH_STACK (&args, upcall_s_log_type );
475
481
}
476
482
477
483
struct rust_new_stack2_args {
0 commit comments