parent
41528dc543
commit
2ff89469d4
1 changed files with 49 additions and 31 deletions
|
@ -62,7 +62,9 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
|
||||||
// FIXME: would be nice to have a constraint on arg
|
// FIXME: would be nice to have a constraint on arg
|
||||||
// that would obviate the need for this check
|
// that would obviate the need for this check
|
||||||
check non_ty_var(cx, arg_ty);
|
check non_ty_var(cx, arg_ty);
|
||||||
atys += [T_ptr(type_of_inner(cx, sp, arg_ty))];
|
let llty = type_of_inner(cx, sp, arg_ty);
|
||||||
|
if arg.mode == ast::by_val { atys += [llty]; }
|
||||||
|
else { atys += [T_ptr(llty)]; }
|
||||||
}
|
}
|
||||||
ret atys;
|
ret atys;
|
||||||
}
|
}
|
||||||
|
@ -3424,15 +3426,15 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
|
||||||
env_ty: ty::t, ty_param_count: uint,
|
env_ty: ty::t, ty_param_count: uint,
|
||||||
target_fn: option::t<ValueRef>)
|
target_fn: option::t<ValueRef>)
|
||||||
-> {val: ValueRef, ty: TypeRef} {
|
-> {val: ValueRef, ty: TypeRef} {
|
||||||
// If we supported constraints on record fields, we could make the
|
// If we supported constraints on record fields, we could make the
|
||||||
// constraints for this function:
|
// constraints for this function:
|
||||||
/*
|
/*
|
||||||
: returns_non_ty_var(ccx, outgoing_fty),
|
: returns_non_ty_var(ccx, outgoing_fty),
|
||||||
type_has_static_size(ccx, incoming_fty) ->
|
type_has_static_size(ccx, incoming_fty) ->
|
||||||
*/
|
*/
|
||||||
// but since we don't, we have to do the checks at the beginning.
|
// but since we don't, we have to do the checks at the beginning.
|
||||||
let ccx = cx.ccx;
|
let ccx = cx.ccx;
|
||||||
check type_has_static_size(ccx, incoming_fty);
|
check type_has_static_size(ccx, incoming_fty);
|
||||||
|
|
||||||
// Here we're not necessarily constructing a thunk in the sense of
|
// Here we're not necessarily constructing a thunk in the sense of
|
||||||
// "function with no arguments". The result of compiling 'bind f(foo,
|
// "function with no arguments". The result of compiling 'bind f(foo,
|
||||||
|
@ -3566,6 +3568,7 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
|
||||||
abi::closure_elt_bindings, b]);
|
abi::closure_elt_bindings, b]);
|
||||||
bcx = bound_arg.bcx;
|
bcx = bound_arg.bcx;
|
||||||
let val = bound_arg.val;
|
let val = bound_arg.val;
|
||||||
|
if out_arg.mode == ast::by_val { val = Load(bcx, val); }
|
||||||
// If the type is parameterized, then we need to cast the
|
// If the type is parameterized, then we need to cast the
|
||||||
// type we actually have to the parameterized out type.
|
// type we actually have to the parameterized out type.
|
||||||
if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) {
|
if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) {
|
||||||
|
@ -3700,21 +3703,24 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
|
||||||
// to have type lldestty0 (the callee's expected type).
|
// to have type lldestty0 (the callee's expected type).
|
||||||
val = llvm::LLVMGetUndef(lldestty0);
|
val = llvm::LLVMGetUndef(lldestty0);
|
||||||
} else if arg.mode == ast::by_ref || arg.mode == ast::by_val {
|
} else if arg.mode == ast::by_ref || arg.mode == ast::by_val {
|
||||||
let copied = false;
|
let copied = false, imm = type_is_immediate(ccx, e_ty);
|
||||||
if !lv.is_mem && type_is_immediate(ccx, e_ty) {
|
if arg.mode == ast::by_ref && !lv.is_mem && imm {
|
||||||
val = do_spill_noroot(bcx, val);
|
val = do_spill_noroot(bcx, val);
|
||||||
copied = true;
|
copied = true;
|
||||||
}
|
}
|
||||||
if ccx.copy_map.contains_key(e.id) && lv.is_mem {
|
if ccx.copy_map.contains_key(e.id) && lv.is_mem {
|
||||||
|
assert lv.is_mem;
|
||||||
if !copied {
|
if !copied {
|
||||||
let alloc = alloc_ty(bcx, e_ty);
|
let alloc = alloc_ty(bcx, e_ty);
|
||||||
bcx =
|
bcx = copy_val(alloc.bcx, INIT, alloc.val,
|
||||||
copy_val(alloc.bcx, INIT, alloc.val,
|
load_if_immediate(alloc.bcx, val, e_ty), e_ty);
|
||||||
load_if_immediate(alloc.bcx, val, e_ty), e_ty);
|
|
||||||
val = alloc.val;
|
val = alloc.val;
|
||||||
} else { bcx = take_ty(bcx, val, e_ty); }
|
} else { bcx = take_ty(bcx, val, e_ty); }
|
||||||
add_clean(bcx, val, e_ty);
|
add_clean(bcx, val, e_ty);
|
||||||
}
|
}
|
||||||
|
if arg.mode == ast::by_val && (lv.is_mem || !imm) {
|
||||||
|
val = Load(bcx, val);
|
||||||
|
}
|
||||||
} else if type_is_immediate(ccx, e_ty) && !lv.is_mem {
|
} else if type_is_immediate(ccx, e_ty) && !lv.is_mem {
|
||||||
let r = do_spill(bcx, val, e_ty);
|
let r = do_spill(bcx, val, e_ty);
|
||||||
val = r.val;
|
val = r.val;
|
||||||
|
@ -3960,7 +3966,8 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr,
|
||||||
|
|
||||||
let r = trans_arg_expr(bcx, ty_arg, llargty, to_zero, to_revoke, arg);
|
let r = trans_arg_expr(bcx, ty_arg, llargty, to_zero, to_revoke, arg);
|
||||||
let llargval = r.val; bcx = r.bcx;
|
let llargval = r.val; bcx = r.bcx;
|
||||||
{ llval: llargval, llty: llargty, static: static }
|
{ llval: llargval, llty: llargty, static: static,
|
||||||
|
by_val: ty_arg.mode == ast::by_val }
|
||||||
}, fn_arg_tys, args);
|
}, fn_arg_tys, args);
|
||||||
|
|
||||||
// Allocate the argument bundle.
|
// Allocate the argument bundle.
|
||||||
|
@ -3976,7 +3983,7 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr,
|
||||||
if llarg.static {
|
if llarg.static {
|
||||||
// FIXME: This load is unfortunate. It won't be necessary once we
|
// FIXME: This load is unfortunate. It won't be necessary once we
|
||||||
// have reference types again.
|
// have reference types again.
|
||||||
llargval = Load(bcx, llarg.llval);
|
llargval = llarg.by_val ? llarg.llval : Load(bcx, llarg.llval);
|
||||||
} else {
|
} else {
|
||||||
llargval = llarg.llval;
|
llargval = llarg.llval;
|
||||||
}
|
}
|
||||||
|
@ -5141,27 +5148,38 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
|
||||||
arg_tys: [ty::arg], ignore_mut: bool)
|
arg_tys: [ty::arg], ignore_mut: bool)
|
||||||
-> @block_ctxt {
|
-> @block_ctxt {
|
||||||
let arg_n: uint = 0u;
|
let arg_n: uint = 0u;
|
||||||
for aarg: ast::arg in args {
|
for arg in arg_tys {
|
||||||
let arg_ty = arg_tys[arg_n].ty;
|
let id = args[arg_n].id;
|
||||||
alt aarg.mode {
|
let mutated = !ignore_mut && fcx.lcx.ccx.mut_map.contains_key(id);
|
||||||
|
alt arg.mode {
|
||||||
|
ast::mode_infer. {
|
||||||
|
bcx_ccx(bcx).sess.span_fatal(fcx.sp, "this");
|
||||||
|
}
|
||||||
ast::by_move. {
|
ast::by_move. {
|
||||||
add_clean(bcx, fcx.llargs.get(aarg.id), arg_ty);
|
add_clean(bcx, fcx.llargs.get(id), arg.ty);
|
||||||
}
|
}
|
||||||
ast::by_mut_ref. { }
|
ast::by_mut_ref. { }
|
||||||
_ {
|
ast::by_val. {
|
||||||
let mutated =
|
let aval = fcx.llargs.get(id);
|
||||||
!ignore_mut && fcx.lcx.ccx.mut_map.contains_key(aarg.id);
|
let {bcx: cx, val: alloc} = alloc_ty(bcx, arg.ty);
|
||||||
|
bcx = cx;
|
||||||
|
Store(bcx, aval, alloc);
|
||||||
|
if mutated {
|
||||||
|
bcx = take_ty(bcx, alloc, arg.ty);
|
||||||
|
add_clean(bcx, alloc, arg.ty);
|
||||||
|
}
|
||||||
|
fcx.llargs.insert(id, alloc);
|
||||||
|
}
|
||||||
|
ast::by_ref. {
|
||||||
// Overwrite the llargs entry for locally mutated params
|
// Overwrite the llargs entry for locally mutated params
|
||||||
// with a local alloca.
|
// with a local alloca.
|
||||||
if mutated {
|
if mutated {
|
||||||
let aptr = fcx.llargs.get(aarg.id);
|
let aptr = fcx.llargs.get(id);
|
||||||
let {bcx: bcx, val: alloc} = alloc_ty(bcx, arg_ty);
|
let {bcx: cx, val: alloc} = alloc_ty(bcx, arg.ty);
|
||||||
bcx =
|
bcx = copy_val(cx, INIT, alloc,
|
||||||
copy_val(bcx, INIT, alloc,
|
load_if_immediate(cx, aptr, arg.ty), arg.ty);
|
||||||
load_if_immediate(bcx, aptr, arg_ty), arg_ty);
|
fcx.llargs.insert(id, alloc);
|
||||||
fcx.llargs.insert(aarg.id, alloc);
|
add_clean(bcx, alloc, arg.ty);
|
||||||
add_clean(bcx, alloc, arg_ty);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5845,7 +5863,7 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
|
||||||
let i = arg_n;
|
let i = arg_n;
|
||||||
for arg: ty::arg in args {
|
for arg: ty::arg in args {
|
||||||
let llarg = llvm::LLVMGetParam(fcx.llfn, i);
|
let llarg = llvm::LLVMGetParam(fcx.llfn, i);
|
||||||
if arg.mode == ast::by_ref || arg.mode == ast::by_val {
|
if arg.mode == ast::by_ref {
|
||||||
llarg = load_if_immediate(bcx, llarg, arg.ty);
|
llarg = load_if_immediate(bcx, llarg, arg.ty);
|
||||||
}
|
}
|
||||||
assert (llarg as int != 0);
|
assert (llarg as int != 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue