From 9aa78e34e47074db22777c35bbf6cf2b3f973c40 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 9 Mar 2012 10:47:40 +0100 Subject: [PATCH] Never pass tydesc to functions My assumption that native generics needed them was wrong, so tydescs can be eliminated from function signatures completely. --- src/rustc/middle/trans/base.rs | 159 +++++++++++----------------- src/rustc/middle/trans/closure.rs | 66 +++--------- src/rustc/middle/trans/common.rs | 2 +- src/rustc/middle/trans/impl.rs | 166 ++---------------------------- src/rustc/middle/trans/native.rs | 21 ++-- src/rustc/middle/trans/type_of.rs | 30 +----- 6 files changed, 93 insertions(+), 351 deletions(-) diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index ef4e17bb368..b20c502013b 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -865,7 +865,7 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t]) maybe_instantiate_inline(ccx, did) } else { did }; assert did.crate == ast::local_crate; - option::get(monomorphic_fn(ccx, did, substs, none)) + monomorphic_fn(ccx, did, substs, none) } fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id, @@ -1951,8 +1951,7 @@ enum callee_env { type lval_maybe_callee = {bcx: block, val: ValueRef, kind: lval_kind, - env: callee_env, - tds: option<[ValueRef]>}; + env: callee_env}; fn null_env_ptr(bcx: block) -> ValueRef { C_null(T_opaque_box_ptr(bcx.ccx())) @@ -1971,20 +1970,21 @@ fn lval_temp(bcx: block, val: ValueRef) -> lval_result { fn lval_no_env(bcx: block, val: ValueRef, kind: lval_kind) -> lval_maybe_callee { - ret {bcx: bcx, val: val, kind: kind, env: is_closure, tds: none}; + ret {bcx: bcx, val: val, kind: kind, env: is_closure}; } -fn trans_external_path(cx: block, did: ast::def_id, - tpt: ty::ty_param_bounds_and_ty) -> ValueRef { - let ccx = cx.fcx.ccx; +fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t) + -> ValueRef { let name = csearch::get_symbol(ccx.sess.cstore, did); - ret get_extern_const(ccx.externs, ccx.llmod, name, - type_of_ty_param_bounds_and_ty(ccx, tpt)); + let llty = alt ty::get(t).struct { + ty::ty_fn(_) { type_of_fn_from_ty(ccx, t) } + _ { type_of(ccx, t) } + }; + ret get_extern_const(ccx.externs, ccx.llmod, name, llty); } fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], - vtables: option) - -> option { + vtables: option) -> ValueRef { let substs = vec::map(substs, {|t| alt ty::get(t).struct { ty::ty_box(mt) { ty::mk_opaque_box(ccx.tcx) } @@ -1996,7 +1996,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], none { no_vts } }}; alt ccx.monomorphized.find(hash_id) { - some(val) { ret some(val); } + some(val) { ret val; } none {} } @@ -2017,8 +2017,10 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], } ast_map::node_variant(v, _, pt) { (pt, v.node.name) } ast_map::node_method(m, _, pt) { (pt, m.ident) } - // We can't monomorphize native functions - ast_map::node_native_item(_, _, _) { ret none; } + ast_map::node_native_item(_, _, _) { + // Natives don't have to be monomorphized. + ret get_item_val(ccx, fn_id.node); + } ast_map::node_ctor(i) { alt check ccx.tcx.items.get(i.id) { ast_map::node_item(i, pt) { (pt, i.ident) } @@ -2027,7 +2029,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], _ { fail "unexpected node type"; } }; let mono_ty = ty::substitute_type_params(ccx.tcx, substs, item_ty); - let llfty = type_of_fn_from_ty(ccx, mono_ty, 0u); + let llfty = type_of_fn_from_ty(ccx, mono_ty); let pt = *pt + [path_name(ccx.names(name))]; let s = mangle_exported_name(ccx, pt, mono_ty); @@ -2071,7 +2073,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], } } } - some(lldecl) + lldecl } fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id) @@ -2142,39 +2144,18 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id, maybe_instantiate_inline(ccx, fn_id) } else { fn_id }; - // The awkwardness below mostly stems from the fact that we're mixing - // monomorphized and non-monomorphized functions at the moment. If - // monomorphizing becomes the only approach, this'll be much simpler. if fn_id.crate == ast::local_crate { - let mono = alt substs { - some((stys, vtables)) { - if stys.len() > 0u { - monomorphic_fn(ccx, fn_id, stys, some(vtables)) - } else { none } - } - none { - alt ccx.maps.vtable_map.find(id) { - some(vtables) { - let rvtables = impl::resolve_vtables_in_fn_ctxt( - bcx.fcx, vtables); - monomorphic_fn(ccx, fn_id, tys, some(rvtables)) - } - none { - if tys.len() == 0u { none } - else { monomorphic_fn(ccx, fn_id, tys, none) } - } - } - } + let (tys, vtables) = alt substs { + some((tys, vts)) { (tys, some(vts)) } + none { (tys, option::map(ccx.maps.vtable_map.find(id), {|vts| + impl::resolve_vtables_in_fn_ctxt(bcx.fcx, vts)})) } }; - alt mono { - some(llfn) { - let cast = PointerCast(bcx, llfn, T_ptr(type_of_fn_from_ty( - ccx, node_id_type(bcx, id), 0u))); + if tys.len() > 0u { + let val = monomorphic_fn(ccx, fn_id, tys, vtables); + let cast = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty( + ccx, node_id_type(bcx, id)))); ret {bcx: bcx, val: cast, - kind: owned, env: null_env, - tds: none}; - } - none {} + kind: owned, env: null_env}; } } @@ -2183,8 +2164,14 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id, get_item_val(ccx, fn_id.node) } else { // External reference. - trans_external_path(bcx, fn_id, tpt) + trans_external_path(ccx, fn_id, tpt.ty) }; + if tys.len() > 0u { + // This is supposed to be an external native function. + // Unfortunately, I found no easy/cheap way to assert that. + val = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty( + ccx, node_id_type(bcx, id)))); + } // FIXME: Need to support external crust functions if fn_id.crate == ast::local_crate { @@ -2198,22 +2185,7 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id, } } - let tds = none, bcx = bcx; - // FIXME[mono] ensure this is a native function - if tys.len() > 0u { - val = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty( - ccx, node_id_type(bcx, id), tys.len()))); - let tydescs = []; - for t in tys { - let ti = none; - let td = get_tydesc(bcx, t, ti); - lazily_emit_all_tydesc_glue(ccx, ti); - bcx = td.bcx; - tydescs += [td.val]; - } - tds = some(tydescs); - } - ret {bcx: bcx, val: val, kind: owned, env: null_env, tds: tds}; + ret {bcx: bcx, val: val, kind: owned, env: null_env}; } fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef { @@ -2313,7 +2285,7 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id, path: @ast::path) ret lval_no_env(cx, get_item_val(ccx, did.node), owned); } else { let tp = node_id_type(cx, id); - let val = trans_external_path(cx, did, {bounds: @[], ty: tp}); + let val = trans_external_path(ccx, did, tp); ret lval_no_env(cx, load_if_immediate(cx, val, tp), owned_imm); } } @@ -2466,8 +2438,7 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result { } fn lval_maybe_callee_to_lval(c: lval_maybe_callee, ty: ty::t) -> lval_result { - let must_bind = option::is_some(c.tds) || - alt c.env { self_env(_, _) { true } _ { false } }; + let must_bind = alt c.env { self_env(_, _) { true } _ { false } }; if must_bind { let n_args = ty::ty_fn_args(ty).len(); let args = vec::from_elem(n_args, none); @@ -2662,12 +2633,10 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr, // - create_llargs_for_fn_args. // - new_fn_ctxt // - trans_args -fn trans_args(cx: block, llenv: ValueRef, - tds: option<[ValueRef]>, es: [@ast::expr], fn_ty: ty::t, - dest: dest) - -> {bcx: block, - args: [ValueRef], - retslot: ValueRef} { +fn trans_args(cx: block, llenv: ValueRef, es: [@ast::expr], fn_ty: ty::t, + dest: dest) -> {bcx: block, + args: [ValueRef], + retslot: ValueRef} { let temp_cleanups = []; let args = ty::ty_fn_args(fn_ty); @@ -2701,12 +2670,6 @@ fn trans_args(cx: block, llenv: ValueRef, // Arg 1: Env (closure-bindings / self value) llargs += [llenv]; - // Args >2: ty_params ... - alt tds { - some(tds) { llargs += tds; } - none {} - } - // ... then explicit args. // First we figure out the caller's view of the types of the arguments. @@ -2770,8 +2733,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, }; let ret_ty = node_id_type(bcx, id); - let args_res = - trans_args(bcx, llenv, f_res.tds, args, fn_expr_ty, dest); + let args_res = trans_args(bcx, llenv, args, fn_expr_ty, dest); bcx = args_res.bcx; let llargs = args_res.args; let llretslot = args_res.retslot; @@ -3883,7 +3845,7 @@ fn create_llargs_for_fn_args(cx: fn_ctxt, args: [ast::arg], tps_bounds: [ty::param_bounds]) { // Skip the implicit arguments 0, and 1. - let arg_n = first_tp_arg; + let arg_n = first_real_arg; alt ty_self { impl_self(tt) { cx.llself = some({v: cx.llenv, t: tt}); @@ -4417,11 +4379,9 @@ fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef { } fn register_fn(ccx: @crate_ctxt, sp: span, path: path, flav: str, - ty_params: [ast::ty_param], node_id: ast::node_id) - -> ValueRef { + node_id: ast::node_id) -> ValueRef { let t = ty::node_id_to_type(ccx.tcx, node_id); - let bnds = param_bounds(ccx, ty_params); - register_fn_full(ccx, sp, path, flav, bnds, node_id, t) + register_fn_full(ccx, sp, path, flav, node_id, t) } fn param_bounds(ccx: @crate_ctxt, tps: [ast::ty_param]) @@ -4430,9 +4390,8 @@ fn param_bounds(ccx: @crate_ctxt, tps: [ast::ty_param]) } fn register_fn_full(ccx: @crate_ctxt, sp: span, path: path, flav: str, - bnds: [ty::param_bounds], node_id: ast::node_id, - node_type: ty::t) -> ValueRef { - let llfty = type_of_fn_from_ty(ccx, node_type, bnds.len()); + node_id: ast::node_id, node_type: ty::t) -> ValueRef { + let llfty = type_of_fn_from_ty(ccx, node_type); register_fn_fuller(ccx, sp, path, flav, node_id, node_type, lib::llvm::CCallConv, llfty) } @@ -4479,7 +4438,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, {mode: ast::expl(ast::by_val), ty: ty::mk_vec(ccx.tcx, {ty: unit_ty, mutbl: ast::m_imm})}; let nt = ty::mk_nil(ccx.tcx); - let llfty = type_of_fn(ccx, [vecarg_ty], nt, 0u); + let llfty = type_of_fn(ccx, [vecarg_ty], nt); let llfdecl = decl_fn(ccx.llmod, "_rust_main", lib::llvm::CCallConv, llfty); @@ -4575,16 +4534,16 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { ccx.item_symbols.insert(i.id, s); g } - ast::item_fn(decl, tps, _) { + ast::item_fn(decl, _, _) { let llfn = if decl.purity != ast::crust_fn { - register_fn(ccx, i.span, my_path, "fn", tps, i.id) + register_fn(ccx, i.span, my_path, "fn", i.id) } else { native::register_crust_fn(ccx, i.span, my_path, i.id) }; set_inline_hint_if_appr(i.attrs, llfn); llfn } - ast::item_res(_, tps, _, dtor_id, _) { + ast::item_res(_, _, _, dtor_id, _) { // Note that the destructor is associated with the item's id, // not the dtor_id. This is a bit counter-intuitive, but // simplifies ty_res, which would have to carry around two @@ -4592,17 +4551,15 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { // find the dtor symbol. let t = ty::node_id_to_type(ccx.tcx, dtor_id); register_fn_full(ccx, i.span, my_path + [path_name("dtor")], - "res_dtor", param_bounds(ccx, tps), i.id, t) + "res_dtor", i.id, t) } } } ast_map::node_method(m, impl_id, pth) { let mty = ty::node_id_to_type(ccx.tcx, id); - let impl_tps = *ty::lookup_item_type(ccx.tcx, impl_id).bounds; let pth = *pth + [path_name(int::str(impl_id.node)), path_name(m.ident)]; let llfn = register_fn_full(ccx, m.span, pth, "impl_method", - impl_tps + param_bounds(ccx, m.tps), id, mty); set_inline_hint_if_appr(m.attrs, llfn); llfn @@ -4612,15 +4569,15 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { } ast_map::node_ctor(i) { alt check i.node { - ast::item_res(_, tps, _, _, _) { + ast::item_res(_, _, _, _, _) { let my_path = item_path(ccx, i); let llctor = register_fn(ccx, i.span, my_path, "res_ctor", - tps, id); + id); set_inline_hint(llctor); llctor } - ast::item_class(tps, _, ctor) { - register_fn(ccx, i.span, item_path(ccx, i), "ctor", tps, id) + ast::item_class(_, _, ctor) { + register_fn(ccx, i.span, item_path(ccx, i), "ctor", id) } } } @@ -4628,8 +4585,8 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { assert v.node.args.len() != 0u; let pth = *pth + [path_name(enm.ident), path_name(v.node.name)]; let llfn = alt check enm.node { - ast::item_enum(_, tps) { - register_fn(ccx, v.span, pth, "enum", tps, id) + ast::item_enum(_, _) { + register_fn(ccx, v.span, pth, "enum", id) } }; set_inline_hint(llfn); diff --git a/src/rustc/middle/trans/closure.rs b/src/rustc/middle/trans/closure.rs index eae89f4304c..c67c3f1d456 100644 --- a/src/rustc/middle/trans/closure.rs +++ b/src/rustc/middle/trans/closure.rs @@ -130,17 +130,10 @@ fn mk_tuplified_uniq_cbox_ty(tcx: ty::ctxt, cdata_ty: ty::t) -> ty::t { // Given a closure ty, emits a corresponding tuple ty fn mk_closure_tys(tcx: ty::ctxt, - ck: ty::closure_kind, - ty_params: option<[ValueRef]>, bound_values: [environment_value]) -> (ty::t, [ty::t]) { let bound_tys = []; - // Compute the closed over tydescs - let n_param_ptrs = alt ty_params { - some(tds) { tds.len() } none { 0u } - }; - // Compute the closed over data for bv in bound_values { bound_tys += [alt bv { @@ -151,9 +144,8 @@ fn mk_closure_tys(tcx: ty::ctxt, }]; } let bound_data_ty = ty::mk_tup(tcx, bound_tys); - - let typtrs = vec::from_elem(n_param_ptrs, mk_tydesc_ty(tcx, ck)); - let cdata_ty = ty::mk_tup(tcx, [ty::mk_tup(tcx, typtrs), + // FIXME[mono] remove tuple of tydescs from closure types + let cdata_ty = ty::mk_tup(tcx, [ty::mk_tup(tcx, []), bound_data_ty]); #debug["cdata_ty=%s", ty_to_str(tcx, cdata_ty)]; ret (cdata_ty, bound_tys); @@ -237,11 +229,9 @@ fn cast_if_we_can(bcx: block, llbox: ValueRef, t: ty::t) -> ValueRef { // construct a closure out of them. If copying is true, it is a // heap allocated closure that copies the upvars into environment. // Otherwise, it is stack allocated and copies pointers to the upvars. -fn store_environment( - bcx: block, lltyparams: option<[ValueRef]>, - bound_values: [environment_value], - ck: ty::closure_kind) - -> closure_result { +fn store_environment(bcx: block, + bound_values: [environment_value], + ck: ty::closure_kind) -> closure_result { fn maybe_clone_tydesc(bcx: block, ck: ty::closure_kind, @@ -260,7 +250,7 @@ fn store_environment( // compute the shape of the closure let (cdata_ty, bound_tys) = - mk_closure_tys(tcx, ck, lltyparams, bound_values); + mk_closure_tys(tcx, bound_values); // allocate closure in the heap let (bcx, llbox, temp_cleanups) = @@ -274,18 +264,6 @@ fn store_environment( let llbox = cast_if_we_can(bcx, llbox, cboxptr_ty); #debug["tuplify_box_ty = %s", ty_to_str(tcx, cbox_ty)]; - // If necessary, copy tydescs describing type parameters into the - // appropriate slot in the closure. - let {bcx:bcx, val:ty_params_slot} = - GEP_tup_like(bcx, cbox_ty, llbox, - [0, abi::box_field_body, abi::closure_body_ty_params]); - option::may(lltyparams) {|tds| - vec::iteri(tds) {|i, td| - let cloned_td = maybe_clone_tydesc(bcx, ck, td); - Store(bcx, cloned_td, GEPi(bcx, ty_params_slot, [0, i as int])); - } - } - // Copy expr values into boxed bindings. vec::iteri(bound_values) { |i, bv| #debug["Copy %s into closure", ev_to_str(ccx, bv)]; @@ -377,7 +355,7 @@ fn build_closure(bcx0: block, } } } - ret store_environment(bcx, none, env_vals, ck); + ret store_environment(bcx, env_vals, ck); } // Given an enclosing block context, a new function context, a closure type, @@ -426,11 +404,11 @@ fn trans_expr_fn(bcx: block, if dest == ignore { ret bcx; } let ccx = bcx.ccx(), bcx = bcx; let fty = node_id_type(bcx, id); - let llfnty = type_of_fn_from_ty(ccx, fty, 0u); + let llfnty = type_of_fn_from_ty(ccx, fty); let sub_path = bcx.fcx.path + [path_name("anon")]; let s = mangle_internal_name_by_path(ccx, sub_path); let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty); - register_fn(ccx, sp, sub_path, "anon fn", [], id); + register_fn(ccx, sp, sub_path, "anon fn", id); let trans_closure_env = fn@(ck: ty::closure_kind) -> ValueRef { let cap_vars = capture::compute_capture_vars( @@ -479,7 +457,7 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t, ret bcx; } - if bound.len() == 0u && option::is_none(f_res.tds) && + if bound.len() == 0u && (f_res.env == null_env || f_res.env == is_closure) { // Trivial 'binding': just return the closure let lv = lval_maybe_callee_to_lval(f_res, pair_ty); @@ -505,15 +483,13 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t, // Actually construct the closure let {llbox, cdata_ty, bcx} = store_environment( - bcx, f_res.tds, - env_vals + vec::map(bound, {|x| env_expr(x, expr_ty(bcx, x))}), + bcx, env_vals + vec::map(bound, {|x| env_expr(x, expr_ty(bcx, x))}), ty::ck_box); // Make thunk let llthunk = trans_bind_thunk( cx.fcx.ccx, cx.fcx.path, pair_ty, outgoing_fty, args, - cdata_ty, target_info, - alt f_res.tds { some(x) { x.len() } _ { 0u } }); + cdata_ty, target_info); // Fill the function pair fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, llbox); @@ -665,8 +641,7 @@ fn trans_bind_thunk(ccx: @crate_ctxt, outgoing_fty: ty::t, args: [option<@ast::expr>], cdata_ty: ty::t, - target_info: target_info, - n_tps: uint) + target_info: target_info) -> {val: ValueRef, ty: TypeRef} { let tcx = ccx.tcx; #debug["trans_bind_thunk[incoming_fty=%s,outgoing_fty=%s,\ @@ -769,18 +744,7 @@ fn trans_bind_thunk(ccx: @crate_ctxt, // Set up the three implicit arguments to the thunk. let llargs: [ValueRef] = [llretptr, lltargetenv]; - // Copy in the type parameters. - let {bcx: l_bcx, val: param_record} = - GEP_tup_like(l_bcx, cdata_ty, llcdata, - [0, abi::closure_body_ty_params]); - let i = 0u; - while i < n_tps { - let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, i as int])); - llargs += [dsc]; - fcx.lltyparams += [{desc: dsc, vtables: none}]; - } - - let a: uint = first_tp_arg; // retptr, env come first + let a: uint = first_real_arg; // retptr, env come first let b: int = starting_idx; let outgoing_arg_index: uint = 0u; let llout_arg_tys: [TypeRef] = @@ -838,7 +802,7 @@ fn trans_bind_thunk(ccx: @crate_ctxt, // in the closure does not know how many type descriptors the function // needs to take. let lltargetty = - type_of_fn_from_ty(ccx, outgoing_fty, 0u); + type_of_fn_from_ty(ccx, outgoing_fty); lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty)); Call(bcx, lltargetfn, llargs); build_return(bcx); diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs index 6a287ee126e..f1fc7228791 100644 --- a/src/rustc/middle/trans/common.rs +++ b/src/rustc/middle/trans/common.rs @@ -352,7 +352,7 @@ type block = @{ }; // First two args are retptr, env -const first_tp_arg: uint = 2u; +const first_real_arg: uint = 2u; // FIXME move blocks to a class once those are finished, and simply use // option for this. diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index 11242c02ca5..1a459f717c7 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -74,23 +74,16 @@ fn trans_static_callee(bcx: block, callee_id: ast::node_id, with lval_static_fn(bcx, did, callee_id, substs)} } -fn wrapper_fn_ty(ccx: @crate_ctxt, vtable_ty: TypeRef, fty: ty::t, - tps: @[ty::param_bounds]) -> {ty: ty::t, llty: TypeRef} { - let bare_fn_ty = type_of_fn_from_ty(ccx, fty, (*tps).len()); - let {inputs, output} = llfn_arg_tys(bare_fn_ty); - {ty: fty, llty: T_fn([vtable_ty] + inputs, output)} -} - fn trans_vtable_callee(bcx: block, env: callee_env, vtable: ValueRef, callee_id: ast::node_id, n_method: uint) -> lval_maybe_callee { let bcx = bcx, ccx = bcx.ccx(); let fty = node_id_type(bcx, callee_id); - let llfty = type_of::type_of_fn_from_ty(ccx, fty, 0u); + let llfty = type_of::type_of_fn_from_ty(ccx, fty); let vtable = PointerCast(bcx, vtable, T_ptr(T_array(T_ptr(llfty), n_method + 1u))); let mptr = Load(bcx, GEPi(bcx, vtable, [0, n_method as int])); - {bcx: bcx, val: mptr, kind: owned, env: env, tds: none} + {bcx: bcx, val: mptr, kind: owned, env: env} } fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id, @@ -106,7 +99,7 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id, } } -fn method_ty_param_count(ccx: crate_ctxt, m_id: ast::def_id) -> uint { +fn method_ty_param_count(ccx: @crate_ctxt, m_id: ast::def_id) -> uint { if m_id.crate == ast::local_crate { alt check ccx.tcx.items.get(m_id.node) { ast_map::node_method(m, _, _) { vec::len(m.tps) } @@ -128,7 +121,7 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id, let n_m_tps = method_ty_param_count(ccx, mth_id); let node_substs = node_id_type_params(bcx, callee_id); let ty_substs = impl_substs + - vec::tail_n(node_substs, node_substs.len() - n_m_tps); + vec::tailn(node_substs, node_substs.len() - n_m_tps); ret trans_static_callee(bcx, callee_id, base, mth_id, some((ty_substs, sub_origins))); } @@ -255,161 +248,14 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: [ty::t], let fty = ty::substitute_type_params(tcx, substs, ty::mk_fn(tcx, im.fty)); if (*im.tps).len() > 0u || ty::type_has_vars(fty) { - C_null(type_of_fn_from_ty(ccx, fty, 0u)) + C_null(type_of_fn_from_ty(ccx, fty)) } else { let m_id = method_with_name(ccx, impl_id, im.ident); - option::get(monomorphic_fn(ccx, m_id, substs, some(vtables))) + monomorphic_fn(ccx, m_id, substs, some(vtables)) } })) } -/* -fn make_iface_vtable(ccx: @crate_ctxt, pt: path, it: @ast::item) { - let new_pt = pt + [path_name(it.ident), path_name(int::str(it.id))]; - let i_did = local_def(it.id), i = 0u; - let ptrs = vec::map(*ty::iface_methods(ccx.tcx, i_did), {|m| - let w = trans_iface_wrapper(ccx, new_pt + [path_name(m.ident)], m, i); - i += 1u; - w - }); - let s = link::mangle_internal_name_by_path( - ccx, new_pt + [path_name("!vtable")]); - trans_vtable(ccx, it.id, s, ptrs); -} - -fn dict_is_static(tcx: ty::ctxt, origin: typeck::dict_origin) -> bool { - alt origin { - typeck::dict_static(_, ts, origs) { - vec::all(ts, {|t| !ty::type_has_params(t)}) && - vec::all(*origs, {|o| dict_is_static(tcx, o)}) - } - typeck::dict_iface(_) { true } - _ { false } - } -} - -fn get_dict(bcx: block, origin: typeck::dict_origin) -> result { - let ccx = bcx.ccx(); - alt origin { - typeck::dict_static(impl_did, tys, sub_origins) { - if dict_is_static(ccx.tcx, origin) { - ret rslt(bcx, get_static_dict(bcx, origin)); - } - let {bcx, ptrs} = get_dict_ptrs(bcx, origin); - let pty = T_ptr(T_i8()), dict_ty = T_array(pty, ptrs.len()); - let dict = alloca(bcx, dict_ty), i = 0; - for ptr in ptrs { - Store(bcx, PointerCast(bcx, ptr, pty), GEPi(bcx, dict, [0, i])); - i += 1; - } - dict = Call(bcx, ccx.upcalls.intern_dict, - [C_uint(ccx, ptrs.len()), - PointerCast(bcx, dict, T_ptr(T_dict()))]); - rslt(bcx, dict) - } - typeck::dict_param(n_param, n_bound) { - rslt(bcx, option::get(bcx.fcx.lltyparams[n_param].dicts)[n_bound]) - } - typeck::dict_iface(did) { - ret rslt(bcx, get_static_dict(bcx, origin)); - } - } -} - -fn dict_id(tcx: ty::ctxt, origin: typeck::dict_origin) -> dict_id { - alt origin { - typeck::dict_static(did, ts, origs) { - let d_params = [], orig = 0u; - if ts.len() == 0u { ret @{def: did, params: d_params}; } - let impl_params = ty::lookup_item_type(tcx, did).bounds; - vec::iter2(ts, *impl_params) {|t, bounds| - d_params += [dict_param_ty(t)]; - for bound in *bounds { - alt bound { - ty::bound_iface(_) { - d_params += [dict_param_dict(dict_id(tcx, origs[orig]))]; - orig += 1u; - } - _ {} - } - } - } - @{def: did, params: d_params} - } - typeck::dict_iface(did) { - @{def: did, params: []} - } - _ { - tcx.sess.bug("unexpected dict_param in dict_id"); - } - } -} - -fn get_static_dict(bcx: block, origin: typeck::dict_origin) - -> ValueRef { - let ccx = bcx.ccx(); - let id = dict_id(ccx.tcx, origin); - alt ccx.dicts.find(id) { - some(d) { ret d; } - none {} - } - let ptrs = C_struct(get_dict_ptrs(bcx, origin).ptrs); - let name = ccx.names("dict"); - let gvar = str::as_c_str(name, {|buf| - llvm::LLVMAddGlobal(ccx.llmod, val_ty(ptrs), buf) - }); - llvm::LLVMSetGlobalConstant(gvar, lib::llvm::True); - llvm::LLVMSetInitializer(gvar, ptrs); - lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage); - let cast = llvm::LLVMConstPointerCast(gvar, T_ptr(T_dict())); - ccx.dicts.insert(id, cast); - cast -} - -fn get_dict_ptrs(bcx: block, origin: typeck::dict_origin) - -> {bcx: block, ptrs: [ValueRef]} { - let ccx = bcx.ccx(); - fn get_vtable(ccx: @crate_ctxt, did: ast::def_id) -> ValueRef { - if did.crate == ast::local_crate { - get_item_val(ccx, did.node) - } else { - let name = csearch::get_symbol(ccx.sess.cstore, did); - get_extern_const(ccx.externs, ccx.llmod, name, T_ptr(T_i8())) - } - } - alt origin { - typeck::dict_static(impl_did, tys, sub_origins) { - let impl_params = ty::lookup_item_type(ccx.tcx, impl_did).bounds; - let ptrs = [get_vtable(ccx, impl_did)]; - let origin = 0u, bcx = bcx; - vec::iter2(*impl_params, tys) {|param, ty| - let rslt = get_tydesc_simple(bcx, ty, true); - ptrs += [rslt.val]; - bcx = rslt.bcx; - for bound in *param { - alt bound { - ty::bound_iface(_) { - let res = get_dict(bcx, sub_origins[origin]); - ptrs += [res.val]; - bcx = res.bcx; - origin += 1u; - } - _ {} - } - } - } - {bcx: bcx, ptrs: ptrs} - } - typeck::dict_iface(did) { - {bcx: bcx, ptrs: [get_vtable(ccx, did)]} - } - _ { - bcx.tcx().sess.bug("unexpected dict_param in get_dict_ptrs"); - } - } -} -}*/ - fn trans_cast(bcx: block, val: @ast::expr, id: ast::node_id, dest: dest) -> block { if dest == ignore { ret trans_expr(bcx, val, ignore); } diff --git a/src/rustc/middle/trans/native.rs b/src/rustc/middle/trans/native.rs index 7aa059fb17e..55c5ef679a3 100644 --- a/src/rustc/middle/trans/native.rs +++ b/src/rustc/middle/trans/native.rs @@ -206,15 +206,13 @@ fn trans_native_mod(ccx: @crate_ctxt, fn build_wrap_fn(ccx: @crate_ctxt, tys: @c_stack_tys, - num_tps: uint, llshimfn: ValueRef, llwrapfn: ValueRef) { fn build_args(bcx: block, tys: @c_stack_tys, - llwrapfn: ValueRef, llargbundle: ValueRef, - num_tps: uint) { + llwrapfn: ValueRef, llargbundle: ValueRef) { let i = 0u, n = vec::len(tys.arg_tys); - let implicit_args = first_tp_arg + num_tps; // ret + env + let implicit_args = first_real_arg; // ret + env while i < n { let llargval = llvm::LLVMGetParam( llwrapfn, @@ -233,8 +231,7 @@ fn trans_native_mod(ccx: @crate_ctxt, build_wrap_fn_(ccx, tys, llshimfn, llwrapfn, ccx.upcalls.call_shim_on_c_stack, - bind build_args(_, _ ,_ , _, num_tps), - build_ret); + build_args, build_ret); } let cc = lib::llvm::CCallConv; @@ -249,12 +246,12 @@ fn trans_native_mod(ccx: @crate_ctxt, for native_item in native_mod.items { alt native_item.node { - ast::native_item_fn(fn_decl, tps) { + ast::native_item_fn(fn_decl, _) { let id = native_item.id; let tys = c_stack_tys(ccx, id); let llwrapfn = get_item_val(ccx, id); let llshimfn = build_shim_fn(ccx, native_item, tys, cc); - build_wrap_fn(ccx, tys, vec::len(tps), llshimfn, llwrapfn); + build_wrap_fn(ccx, tys, llshimfn, llwrapfn); } } } @@ -269,7 +266,7 @@ fn trans_crust_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl, let t = ty::node_id_to_type(ccx.tcx, id); let ps = link::mangle_internal_name_by_path( ccx, path + [ast_map::path_name("__rust_abi")]); - let llty = type_of_fn_from_ty(ccx, t, 0u); + let llty = type_of_fn_from_ty(ccx, t); let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty); trans_fn(ccx, path, decl, body, llfndecl, no_self, none, id, none); @@ -377,13 +374,13 @@ fn abi_of_native_fn(ccx: @crate_ctxt, i: @ast::native_item) fn decl_native_fn(ccx: @crate_ctxt, i: @ast::native_item, pth: ast_map::path) -> ValueRef { alt i.node { - ast::native_item_fn(_, tps) { + ast::native_item_fn(_, _) { let node_type = ty::node_id_to_type(ccx.tcx, i.id); alt abi_of_native_fn(ccx, i) { ast::native_abi_rust_intrinsic { // For intrinsics: link the function directly to the intrinsic // function itself. - let fn_type = type_of_fn_from_ty(ccx, node_type, tps.len()); + let fn_type = type_of_fn_from_ty(ccx, node_type); let ri_name = "rust_intrinsic_" + native::link_name(i); ccx.item_symbols.insert(i.id, ri_name); get_extern_fn(ccx.externs, ccx.llmod, ri_name, @@ -394,7 +391,7 @@ fn decl_native_fn(ccx: @crate_ctxt, i: @ast::native_item, // For true external functions: create a rust wrapper // and link to that. The rust wrapper will handle // switching to the C stack. - register_fn(ccx, i.span, pth, "native fn", tps, i.id) + register_fn(ccx, i.span, pth, "native fn", i.id) } } } diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs index a7991563abb..6d4149fa78c 100644 --- a/src/rustc/middle/trans/type_of.rs +++ b/src/rustc/middle/trans/type_of.rs @@ -18,8 +18,7 @@ fn type_of_explicit_args(cx: @crate_ctxt, inputs: [ty::arg]) -> [TypeRef] { } } -fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg], - output: ty::t, n_ty_params: uint) -> TypeRef { +fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg], output: ty::t) -> TypeRef { let atys: [TypeRef] = []; // Arg 0: Output pointer. @@ -28,21 +27,14 @@ fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg], // Arg 1: Environment atys += [T_opaque_box_ptr(cx)]; - // Args >2: ty params, if not acquired via capture... - let i = 0u; - while i < n_ty_params { - atys += [T_ptr(cx.tydesc_type)]; - i += 1u; - } // ... then explicit args. atys += type_of_explicit_args(cx, inputs); ret T_fn(atys, llvm::LLVMVoidType()); } // Given a function type and a count of ty params, construct an llvm type -fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t, n_ty_params: uint) - -> TypeRef { - type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty), n_ty_params) +fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t) -> TypeRef { + type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty)) } fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { @@ -89,7 +81,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { T_struct(tys) } ty::ty_fn(_) { - T_fn_pair(cx, type_of_fn_from_ty(cx, t, 0u)) + T_fn_pair(cx, type_of_fn_from_ty(cx, t)) } ty::ty_iface(_, _) { T_opaque_iface(cx) } ty::ty_res(_, sub, tps) { @@ -146,20 +138,6 @@ fn type_of_enum(cx: @crate_ctxt, did: ast::def_id, t: ty::t) } } -fn type_of_ty_param_bounds_and_ty - (ccx: @crate_ctxt, tpt: ty::ty_param_bounds_and_ty) -> TypeRef { - let t = tpt.ty; - alt ty::get(t).struct { - ty::ty_fn(_) { - ret type_of_fn_from_ty(ccx, t, (*tpt.bounds).len()); - } - _ { - // fall through - } - } - type_of(ccx, t) -} - fn type_of_or_i8(ccx: @crate_ctxt, typ: ty::t) -> TypeRef { if check type_has_static_size(ccx, typ) { type_of(ccx, typ)