Created
May 25, 2011 00:42
-
-
Save eholk/990083 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs | |
index db389fc..3e8447a 100644 | |
--- a/src/comp/middle/trans.rs | |
+++ b/src/comp/middle/trans.rs | |
@@ -5929,7 +5929,10 @@ fn trans_spawn(&@block_ctxt cx, | |
// | |
// 3. Fill the tuple with the arguments we evaluated. | |
// | |
- // 4. Pass a pointer to the spawnee function and the argument tuple to | |
+ // 3.5. Generate a wrapper function that takes the tuple and unpacks it to | |
+ // call the real task. | |
+ // | |
+ // 4. Pass a pointer to the wrapper function and the argument tuple to | |
// upcall_start_task. | |
// | |
// 5. Oh yeah, we have to create the task before we start it... | |
@@ -5987,19 +5990,23 @@ fn trans_spawn(&@block_ctxt cx, | |
auto llfnptr = bcx.build.GEP(fnptr.val, | |
[C_int(0), C_int(0)]); | |
- log_err "Casting llfnptr"; | |
+ | |
auto llfnptrptr_i = bcx.build.PointerCast(llfnptr, | |
T_ptr(T_int())); | |
// We'd better dereference this one more time, since that one points into | |
// the symbol table or something. | |
auto llfnptr_i = bcx.build.Load(llfnptrptr_i); | |
- log_err "Cassting llargs"; | |
auto llargs_i = bcx.build.PointerCast(llargs.val, | |
T_int()); | |
auto args_size = size_of(bcx, args_ty).val; | |
+ // Generate the wrapper function | |
+ auto wrapper = mk_spawn_wrapper(bcx, tname, func, args_ty); | |
+ // TODO: update bcx? | |
+ | |
+ // And start the task | |
bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.start_task, | |
[bcx.fcx.lltaskptr, new_task, | |
llfnptr_i, llargs_i, args_size]); | |
@@ -6028,6 +6035,41 @@ fn trans_spawn(&@block_ctxt cx, | |
ret res(bcx, new_task); | |
} | |
+fn mk_spawn_wrapper(&@block_ctxt cx, | |
+ &str tname, | |
+ &@ast::expr func, | |
+ &ty::t args_ty) -> result { | |
+ auto llmod = cx.fcx.lcx.ccx.llmod; | |
+ let TypeRef args_ty_tref = type_of(cx.fcx.lcx.ccx, cx.sp, args_ty); | |
+ auto llfndecl = decl_cdecl_fn(llmod, tname, | |
+ T_fn([args_ty_tref], T_void())); | |
+ | |
+ auto fcx = new_fn_ctxt(cx.fcx.lcx, cx.sp, llfndecl); | |
+ | |
+ auto fbcx = new_top_block_ctxt(fcx); | |
+ | |
+ // 3u to skip the three implicit args | |
+ let ValueRef arg = llvm::LLVMGetParam(fcx.llfn, 3u); | |
+ | |
+ let vec[ValueRef] child_args = []; | |
+ | |
+ alt(ty::struct(fcx.lcx.ccx.tcx, args_ty)) { | |
+ case(ty::ty_tup(?elements)) { | |
+ auto i = 0; | |
+ for(ty::mt m in elements) { | |
+ // TODO find a new block context | |
+ auto src = fbcx.build.GEP(arg, [C_int(0), C_int(i)]); | |
+ i += 1; | |
+ | |
+ auto arg = fbcx.build.Load(src); | |
+ child_args += [arg]; | |
+ } | |
+ } | |
+ } | |
+ | |
+ fail; | |
+} | |
+ | |
fn trans_send(&@block_ctxt cx, &@ast::expr lhs, &@ast::expr rhs, | |
&ast::ann ann) -> result { | |
auto bcx = cx; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment