Skip to content

Instantly share code, notes, and snippets.

@eholk
Created May 26, 2011 00:59
Show Gist options
  • Save eholk/992331 to your computer and use it in GitHub Desktop.
Save eholk/992331 to your computer and use it in GitHub Desktop.
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);
//let TypeRef wrapper_fn_type = T_fn([args_ty_tref], T_void());
let TypeRef wrapper_fn_type =
type_of_fn(cx.fcx.lcx.ccx, cx.sp, ast::proto_fn,
[rec(mode = ty::mo_alias, ty = args_ty)],
ty::idx_nil,
0u);
log_err #fmt("wrapper args type: %s",
ty_str(cx.fcx.lcx.ccx.tn, args_ty_tref));
log_err #fmt("wrapper fn desired type: %s",
ty_str(cx.fcx.lcx.ccx.tn, wrapper_fn_type));
// TODO: construct a name based on tname
auto llfndecl = decl_cdecl_fn(llmod, "spawn_wrap",
wrapper_fn_type);
log_err #fmt("spawn wrapper decl type: %s",
val_str(cx.fcx.lcx.ccx.tn, llfndecl));
auto fcx = new_fn_ctxt(cx.fcx.lcx, cx.sp, llfndecl);
auto fbcx = new_top_block_ctxt(fcx);
log_err #fmt("spawn wrapper type: %s", val_str(fcx.lcx.ccx.tn,
fcx.llfn));
// 3u to skip the three implicit args
let ValueRef arg = llvm::LLVMGetParam(fcx.llfn, 3u);
log_err #fmt("arg type: %s", val_str(fbcx.fcx.lcx.ccx.tn, arg));
let vec[ValueRef] child_args =
[llvm::LLVMGetParam(fcx.llfn, 0u),
llvm::LLVMGetParam(fcx.llfn, 1u),
llvm::LLVMGetParam(fcx.llfn, 2u)];
// unpack the arguments
alt(ty::struct(fcx.lcx.ccx.tcx, args_ty)) {
case(ty::ty_tup(?elements)) {
auto i = 0;
for(ty::mt m in elements) {
log_err #fmt("GEP arg %d", i);
auto src = fbcx.build.GEP(arg, [C_int(0), C_int(i)]);
i += 1;
log_err #fmt("generating load of type %s",
val_str(fbcx.fcx.lcx.ccx.tn,
src));
auto child_arg = fbcx.build.Load(src);
child_args += [child_arg];
}
}
}
// Find the function
auto fnptr = trans_lval(fbcx, func).res;
fbcx = fnptr.bcx;
log_err "SPAWN 1";
auto llfnptr = fbcx.build.GEP(fnptr.val,
[C_int(0), C_int(0)]);
auto llfn = fbcx.build.Load(llfnptr);
log_err #fmt("Generating call to child function: %s",
val_str(fbcx.fcx.lcx.ccx.tn,
llfn));
auto i = 0;
for(ValueRef v in child_args) {
log_err #fmt("Arg %d: %s",
i,
val_str(fbcx.fcx.lcx.ccx.tn,
v));
i += 1;
}
fbcx.build.Call(llfn,
child_args);
fbcx.build.RetVoid();
finish_fn(fcx, fbcx.llbb);
// TODO: make sure we clean up everything we need to.
ret res(cx, llfndecl);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment