Skip to content

Commit 810c1a9

Browse files
committed
---
yaml --- r: 723 b: refs/heads/master c: f5787ed h: refs/heads/master i: 721: f186573 719: 00181f8 v: v3
1 parent bc0ad08 commit 810c1a9

File tree

3 files changed

+72
-18
lines changed

3 files changed

+72
-18
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: a2f4d9089a413842c96e14e66462577bf14e76fb
2+
refs/heads/master: f5787ed80c2a364754415d0ab0ea6668543938ce

trunk/src/comp/back/abi.rs

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ fn yield_glue_name() -> str {
4848
ret "rust_yield_glue";
4949
}
5050

51+
fn exit_task_glue_name() -> str {
52+
ret "rust_exit_task_glue";
53+
}
54+
5155
//
5256
// Local Variables:
5357
// mode: rust

trunk/src/comp/middle/trans.rs

+67-17
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import lib.llvm.True;
2525

2626
type glue_fns = rec(ValueRef activate_glue,
2727
ValueRef yield_glue,
28+
ValueRef exit_task_glue,
2829
vec[ValueRef] upcall_glues);
2930

3031
type trans_ctxt = rec(session.session sess,
@@ -240,32 +241,48 @@ fn new_builder(BasicBlockRef llbb) -> builder {
240241
ret builder(llbuild);
241242
}
242243

243-
fn trans_block(@fn_ctxt cx, &ast.block b, terminator term) {
244+
fn new_block_ctxt(@fn_ctxt cx, terminator term) -> @block_ctxt {
244245
let BasicBlockRef llbb =
245246
llvm.LLVMAppendBasicBlock(cx.llfn, _str.buf(""));
246-
auto bcx = @rec(llbb=llbb,
247-
build=new_builder(llbb),
248-
term=term,
249-
fcx=cx);
247+
ret @rec(llbb=llbb,
248+
build=new_builder(llbb),
249+
term=term,
250+
fcx=cx);
251+
}
252+
253+
fn trans_block(@fn_ctxt cx, &ast.block b, terminator term) {
254+
auto bcx = (new_block_ctxt(cx, term));
250255
for (@ast.stmt s in b) {
251256
trans_stmt(bcx, *s);
252257
}
253258
bcx.term(cx, bcx.build);
254259
}
255260

256-
fn trans_fn(@trans_ctxt cx, &ast._fn f) {
257-
let vec[TypeRef] args = vec(T_ptr(T_int()), // outptr.
258-
T_taskptr() // taskptr
261+
fn new_fn_ctxt(@trans_ctxt cx,
262+
str name,
263+
TypeRef T_out,
264+
vec[TypeRef] T_explicit_args) -> @fn_ctxt {
265+
let vec[TypeRef] args = vec(T_ptr(T_out), // outptr.
266+
T_taskptr() // taskptr
259267
);
260-
let ValueRef llfn = decl_cdecl_fn(cx.llmod, cx.path, args, T_nil());
268+
args += T_explicit_args;
269+
let ValueRef llfn = decl_cdecl_fn(cx.llmod, name, args, T_nil());
261270
cx.fns.insert(cx.path, llfn);
262271
let ValueRef lloutptr = llvm.LLVMGetParam(llfn, 0u);
263272
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 1u);
264-
auto fcx = @rec(llfn=llfn,
265-
lloutptr=lloutptr,
266-
lltaskptr=lltaskptr,
267-
tcx=cx);
273+
ret @rec(llfn=llfn,
274+
lloutptr=lloutptr,
275+
lltaskptr=lltaskptr,
276+
tcx=cx);
277+
}
278+
279+
fn trans_fn(@trans_ctxt cx, &ast._fn f) {
280+
let TypeRef out = T_int();
281+
let vec[TypeRef] args = vec();
282+
283+
auto fcx = new_fn_ctxt(cx, cx.path, out, args);
268284
auto term = default_terminate;
285+
269286
trans_block(fcx, f.body, term);
270287
}
271288

@@ -292,6 +309,24 @@ fn p2i(ValueRef v) -> ValueRef {
292309
ret llvm.LLVMConstPtrToInt(v, T_int());
293310
}
294311

312+
fn trans_exit_task_glue(@trans_ctxt cx) {
313+
let vec[TypeRef] T_args = vec();
314+
let vec[ValueRef] V_args = vec();
315+
auto term = default_terminate;
316+
317+
auto llfn = cx.glues.exit_task_glue;
318+
let ValueRef lloutptr = C_null(T_int());
319+
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 0u);
320+
auto fcx = @rec(llfn=llfn,
321+
lloutptr=lloutptr,
322+
lltaskptr=lltaskptr,
323+
tcx=cx);
324+
325+
auto bcx = new_block_ctxt(fcx, term);
326+
trans_upcall(bcx, "upcall_exit", V_args);
327+
bcx.term(fcx, bcx.build);
328+
}
329+
295330
fn crate_constant(@trans_ctxt cx) -> ValueRef {
296331

297332
let ValueRef crate_ptr =
@@ -306,9 +341,8 @@ fn crate_constant(@trans_ctxt cx) -> ValueRef {
306341
let ValueRef yield_glue_off =
307342
llvm.LLVMConstSub(p2i(cx.glues.yield_glue), crate_addr);
308343

309-
// FIXME: we aren't generating the exit-task glue yet.
310-
// llvm.LLVMConstSub(p2i(cx.glues.exit_task_glue), crate_addr);
311-
let ValueRef exit_task_glue_off = C_null(T_int());
344+
let ValueRef exit_task_glue_off =
345+
llvm.LLVMConstSub(p2i(cx.glues.exit_task_glue), crate_addr);
312346

313347
let ValueRef crate_val =
314348
C_struct(vec(C_null(T_int()), // ptrdiff_t image_base_off
@@ -373,6 +407,22 @@ fn trans_crate(session.session sess, ast.crate crate) {
373407
auto glues = @rec(activate_glue = decl_glue(llmod,
374408
abi.activate_glue_name()),
375409
yield_glue = decl_glue(llmod, abi.yield_glue_name()),
410+
/*
411+
* Note: the signature passed to decl_cdecl_fn here
412+
* looks unusual because it is. It corresponds neither
413+
* to an upcall signature nor a normal rust-ABI
414+
* signature. In fact it is a fake signature, that
415+
* exists solely to acquire the task pointer as an
416+
* argument to the upcall. It so happens that the
417+
* runtime sets up the task pointer as the sole incoming
418+
* argument to the frame that we return into when
419+
* returning to the exit task glue. So this is the
420+
* signature required to retrieve it.
421+
*/
422+
exit_task_glue =
423+
decl_cdecl_fn(llmod, abi.exit_task_glue_name(),
424+
vec(T_taskptr()), T_nil()),
425+
376426
upcall_glues =
377427
_vec.init_fn[ValueRef](bind decl_upcall(llmod, _),
378428
abi.n_upcall_glues as uint));
@@ -385,7 +435,7 @@ fn trans_crate(session.session sess, ast.crate crate) {
385435
path = "_rust");
386436

387437
trans_mod(cx, crate.module);
388-
438+
trans_exit_task_glue(cx);
389439
trans_main_fn(cx, crate_constant(cx));
390440

391441
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf("rust_out.bc"));

0 commit comments

Comments
 (0)