@@ -254,9 +254,9 @@ rust_task::start_rustboot(uintptr_t exit_task_glue,
254
254
255
255
void
256
256
rust_task::start_rustc (uintptr_t exit_task_glue,
257
- uintptr_t spawnee_fn,
258
- uintptr_t args,
259
- size_t callsz)
257
+ uintptr_t spawnee_fn,
258
+ uintptr_t args,
259
+ size_t callsz)
260
260
{
261
261
LOGPTR (dom, " exit-task glue" , exit_task_glue);
262
262
LOGPTR (dom, " from spawnee" , spawnee_fn);
@@ -271,57 +271,38 @@ rust_task::start_rustc(uintptr_t exit_task_glue,
271
271
// see: "Mac OS X ABI Function Call Guide"
272
272
273
273
274
- // Begin synthesizing frames. There are two: a "fully formed"
275
- // exit-task frame at the top of the stack -- that pretends to be
276
- // mid-execution -- and a just-starting frame beneath it that
277
- // starts executing the first instruction of the spawnee. The
278
- // spawnee *thinks* it was called by the exit-task frame above
279
- // it. It wasn't; we put that fake frame in place here, but the
280
- // illusion is enough for the spawnee to return to the exit-task
281
- // frame when it's done, and exit.
274
+ // Begin synthesizing the exit_task_glue frame. We will return to
275
+ // exit_task_glue and it is responsible for calling the user code
276
+ // and passing the value returned by the user to the system
277
+ // exit routine.
282
278
uintptr_t *spp = (uintptr_t *)rust_sp;
283
279
280
+ uintptr_t dummy_ret = (uintptr_t ) spp--;
284
281
285
- // The exit_task_glue frame we synthesize above the frame we activate:
286
- make_aligned_room_for_bytes (spp, 2 * sizeof (uintptr_t ));
287
- *spp-- = (uintptr_t ) 0 ; // closure-or-obj
288
- *spp-- = (uintptr_t ) this ; // task
289
- I (dom, spp == align_down (spp));
290
- *spp-- = (uintptr_t ) 0x0 ; // output
291
- *spp-- = (uintptr_t ) 0x0 ; // retpc
282
+ uintptr_t args_size = callsz - 3 *sizeof (uintptr_t );
283
+ uintptr_t frame_size = args_size + 4 *sizeof (uintptr_t );
292
284
293
- I (dom, args);
294
- make_aligned_room_for_bytes (spp, callsz - 3 * sizeof (uintptr_t ));
285
+ make_aligned_room_for_bytes (spp, frame_size);
295
286
296
287
// Copy args from spawner to spawnee.
297
288
uintptr_t *src = (uintptr_t *)args;
298
289
src += 1 ; // spawn-call output slot
299
290
src += 1 ; // spawn-call task slot
300
291
src += 1 ; // spawn-call closure-or-obj slot
301
292
302
- // Undo previous sp-- so we're pointing at the last word pushed.
303
- ++spp;
304
-
305
- // Memcpy all but the task, output and env pointers
306
- callsz -= (3 * sizeof (uintptr_t ));
307
- spp = (uintptr_t *) (((uintptr_t )spp) - callsz);
308
- memcpy (spp, src, callsz);
293
+ *spp-- = (uintptr_t ) *src; // vec
294
+ *spp-- = (uintptr_t ) 0x0 ; // closure-or-obj
295
+ *spp-- = (uintptr_t ) this ; // task
296
+ *spp-- = (uintptr_t ) dummy_ret; // output address
309
297
310
- // Move sp down to point to last implicit-arg cell (env).
311
- spp--;
298
+ *spp-- = (uintptr_t ) (uintptr_t ) spawnee_fn;
312
299
313
- // The *implicit* incoming args to the spawnee frame we're
314
- // activating:
315
- *spp-- = (uintptr_t ) 0x0 ; // closure-or-obj
300
+ I (dom, spp == align_down (spp));
316
301
317
- // in FASTCALL mode we don't, the outptr will be in ecx and the task
318
- // in edx, and the activate_glue will make sure to set that up.
302
+ *spp-- = (uintptr_t ) 0x0 ; // retp
319
303
320
- I (dom, spp+1 == align_down (spp+1 ));
321
- *spp-- = (uintptr_t ) exit_task_glue; // retpc
304
+ *spp-- = (uintptr_t ) exit_task_glue;
322
305
323
- // The context the activate_glue needs to switch stack.
324
- *spp-- = (uintptr_t ) spawnee_fn; // instruction to start at
325
306
for (size_t j = 0 ; j < n_callee_saves; ++j) {
326
307
*spp-- = (uintptr_t )NULL ;
327
308
}
0 commit comments