Skip to content

Instantly share code, notes, and snippets.

@eholk
Created May 25, 2011 00:42
Show Gist options
  • Save eholk/990083 to your computer and use it in GitHub Desktop.
Save eholk/990083 to your computer and use it in GitHub Desktop.
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