diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-08 19:02:22 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-15 09:31:34 +0100 |
| commit | 8f84d4c8b6305c960cf51c35a5ea38697d7fa530 (patch) | |
| tree | 0f0e84976e0ba84a8feb360961427fc83ccdf47b /src/rustc | |
| parent | 83c9f585342d6974c5f1847f18ab2b6322b1ea42 (diff) | |
| download | rust-8f84d4c8b6305c960cf51c35a5ea38697d7fa530.tar.gz rust-8f84d4c8b6305c960cf51c35a5ea38697d7fa530.zip | |
Remove a large part of the tydesc-passing code
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/metadata/encoder.rs | 5 | ||||
| -rw-r--r-- | src/rustc/middle/trans/base.rs | 241 | ||||
| -rw-r--r-- | src/rustc/middle/trans/closure.rs | 119 | ||||
| -rw-r--r-- | src/rustc/middle/trans/common.rs | 11 | ||||
| -rw-r--r-- | src/rustc/middle/trans/impl.rs | 12 | ||||
| -rw-r--r-- | src/rustc/middle/trans/native.rs | 5 | ||||
| -rw-r--r-- | src/rustc/middle/trans/shape.rs | 2 | ||||
| -rw-r--r-- | src/rustc/middle/trans/tvec.rs | 2 | ||||
| -rw-r--r-- | src/rustc/middle/trans/type_of.rs | 22 |
9 files changed, 112 insertions, 307 deletions
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 56e7ab47f60..5c6eb30bbeb 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -429,7 +429,9 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_family(ebml_w, 'f'); encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, fn_ty); - encode_symbol(ecx, ebml_w, ctor_id); + if tps.len() == 0u { + encode_symbol(ecx, ebml_w, ctor_id); + } encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml_w.end_tag(); } @@ -447,7 +449,6 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, } alt ifce { some(t) { - encode_symbol(ecx, ebml_w, item.id); let i_ty = alt check t.node { ty_path(_, id) { ty::node_id_to_type(tcx, id) } }; diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 2cf565a9f97..2babf26b3b7 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -270,7 +270,7 @@ fn dynastack_alloca(cx: block, t: TypeRef, n: ValueRef, ty: ty::t) -> C_uint(bcx.ccx(), llsize_of_real(bcx.ccx(), t)), n); - let lltydesc = get_tydesc_simple(cx, ty, false).val; + let lltydesc = get_tydesc_simple(cx, ty).val; let llresult = Call(dy_cx, dynastack_alloc, [llsz, lltydesc]); ret PointerCast(dy_cx, llresult, T_ptr(t)); @@ -450,7 +450,7 @@ fn trans_malloc_boxed_raw(bcx: block, t: ty::t, let llty = type_of(ccx, box_ptr); // Get the tydesc for the body: - let {bcx, val: lltydesc} = get_tydesc(bcx, t, true, static_ti); + let {bcx, val: lltydesc} = get_tydesc(bcx, t, static_ti); lazily_emit_all_tydesc_glue(ccx, static_ti); // Allocate space: @@ -470,37 +470,6 @@ fn trans_malloc_boxed(bcx: block, t: ty::t) -> // Type descriptor and type glue stuff -// Given a type and a field index into its corresponding type descriptor, -// returns an LLVM ValueRef of that field from the tydesc, generating the -// tydesc if necessary. -fn field_of_tydesc(cx: block, t: ty::t, escapes: bool, field: int) -> - result { - let tydesc = get_tydesc_simple(cx, t, escapes); - ret rslt(tydesc.bcx, - GEPi(tydesc.bcx, tydesc.val, [0, field])); -} - -// Given a type containing ty params, build a vector containing a ValueRef for -// each of the ty params it uses (from the current frame) and a vector of the -// indices of the ty params present in the type. This is used solely for -// constructing derived tydescs. -fn linearize_ty_params(cx: block, t: ty::t) -> - {params: [uint], descs: [ValueRef]} { - let param_vals = [], param_defs = []; - ty::walk_ty(cx.tcx(), t) {|t| - alt ty::get(t).struct { - ty::ty_param(pid, _) { - if !vec::any(param_defs, {|d| d == pid}) { - param_vals += [cx.fcx.lltyparams[pid].desc]; - param_defs += [pid]; - } - } - _ { } - } - } - ret {params: param_defs, descs: param_vals}; -} - fn trans_stack_local_derived_tydesc(cx: block, llsz: ValueRef, llalign: ValueRef, llroottydesc: ValueRef, llfirstparam: ValueRef, n_params: uint) @@ -527,93 +496,16 @@ fn trans_stack_local_derived_tydesc(cx: block, llsz: ValueRef, ret llmyroottydesc; } -fn get_derived_tydesc(cx: block, t: ty::t, escapes: bool, - &static_ti: option<@tydesc_info>) -> result { - alt cx.fcx.derived_tydescs.find(t) { - some(info) { - // If the tydesc escapes in this context, the cached derived - // tydesc also has to be one that was marked as escaping. - if !(escapes && !info.escapes) { - ret rslt(cx, info.lltydesc); - } - } - none {/* fall through */ } - } - - cx.ccx().stats.n_derived_tydescs += 1u; - let bcx = raw_block(cx.fcx, cx.fcx.llderivedtydescs); - let tys = linearize_ty_params(bcx, t); - let root_ti = get_static_tydesc(bcx.ccx(), t, tys.params); - static_ti = some(root_ti); - lazily_emit_all_tydesc_glue(cx.ccx(), static_ti); - let root = root_ti.tydesc; - let sz = size_of(bcx, t); - bcx = sz.bcx; - let align = align_of(bcx, t); - bcx = align.bcx; - - // Store the captured type descriptors in an alloca if the caller isn't - // promising to do so itself. - let n_params = ty::count_ty_params(bcx.tcx(), t); - - assert n_params == tys.params.len(); - assert n_params == tys.descs.len(); - - let llparamtydescs = - alloca(bcx, T_array(T_ptr(bcx.ccx().tydesc_type), n_params + 1u)); - let i = 0; - - // If the type descriptor escapes, we need to add in the root as - // the first parameter, because upcall_get_type_desc() expects it. - if escapes { - Store(bcx, root, GEPi(bcx, llparamtydescs, [0, 0])); - i += 1; - } - - for td: ValueRef in tys.descs { - Store(bcx, td, GEPi(bcx, llparamtydescs, [0, i])); - i += 1; - } - - let llfirstparam = - PointerCast(bcx, llparamtydescs, - T_ptr(T_ptr(bcx.ccx().tydesc_type))); - - let v; - if escapes { - let ccx = bcx.ccx(); - let td_val = - Call(bcx, ccx.upcalls.get_type_desc, - [C_null(T_ptr(T_nil())), sz.val, - align.val, C_uint(ccx, 1u + n_params), llfirstparam, - C_uint(ccx, 0u)]); - v = td_val; - } else { - v = trans_stack_local_derived_tydesc(bcx, sz.val, align.val, root, - llfirstparam, n_params); - } - bcx.fcx.derived_tydescs.insert(t, {lltydesc: v, escapes: escapes}); - ret rslt(cx, v); -} - -fn get_tydesc_simple(bcx: block, t: ty::t, escapes: bool) -> result { +fn get_tydesc_simple(bcx: block, t: ty::t) -> result { let ti = none; - get_tydesc(bcx, t, escapes, ti) + get_tydesc(bcx, t, ti) } -fn get_tydesc(cx: block, t: ty::t, escapes: bool, +fn get_tydesc(cx: block, t: ty::t, &static_ti: option<@tydesc_info>) -> result { - // Is the supplied type a type param? If so, return the passed-in tydesc. - alt ty::type_param(t) { - some(id) { ret rslt(cx, cx.fcx.lltyparams[id].desc); } - none {/* fall through */ } - } - - // Does it contain a type param? If so, generate a derived tydesc. - if ty::type_has_params(t) { - ret get_derived_tydesc(cx, t, escapes, static_ti); - } + // FIXME[mono] + assert !ty::type_has_params(t); // Otherwise, generate a tydesc if necessary, and return it. let info = get_static_tydesc(cx.ccx(), t, []); static_ti = some(info); @@ -980,7 +872,7 @@ fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id, let dtor_addr = common::get_res_dtor(ccx, did, inner_t); let args = [bcx.fcx.llretptr, null_env_ptr(bcx)]; for tp in tps { - let td = get_tydesc_simple(bcx, tp, false); + let td = get_tydesc_simple(bcx, tp); args += [td.val]; bcx = td.bcx; } @@ -1244,13 +1136,6 @@ fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt, lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, static_ti); } -fn lazily_emit_all_generic_info_tydesc_glues(ccx: @crate_ctxt, - gi: generic_info) { - for ti: option<@tydesc_info> in gi.static_tis { - lazily_emit_all_tydesc_glue(ccx, ti); - } -} - fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: int, static_ti: option<@tydesc_info>) { alt static_ti { @@ -1349,7 +1234,7 @@ fn call_tydesc_glue_full(cx: block, v: ValueRef, tydesc: ValueRef, fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: int) -> block { let ti: option<@tydesc_info> = none::<@tydesc_info>; - let {bcx: bcx, val: td} = get_tydesc(cx, t, false, ti); + let {bcx: bcx, val: td} = get_tydesc(cx, t, ti); call_tydesc_glue_full(bcx, v, td, field, ti); ret bcx; } @@ -1370,7 +1255,7 @@ fn call_cmp_glue(cx: block, lhs: ValueRef, rhs: ValueRef, t: ty::t, let llrawlhsptr = BitCast(bcx, lllhs, T_ptr(T_i8())); let llrawrhsptr = BitCast(bcx, llrhs, T_ptr(T_i8())); - r = get_tydesc_simple(bcx, t, false); + r = get_tydesc_simple(bcx, t); let lltydesc = r.val; bcx = r.bcx; let lltydescs = @@ -2047,18 +1932,6 @@ fn trans_loop(cx:block, body: ast::blk) -> block { ret next_cx; } -type generic_info = {item_type: ty::t, - static_tis: [option<@tydesc_info>], - tydescs: [ValueRef], - param_bounds: @[ty::param_bounds], - origins: option<typeck::vtable_res>}; - -enum generic_callee { - generic_full(generic_info), - generic_mono(ty::t), - generic_none, -} - enum lval_kind { temporary, //< Temporary value passed by value if of immediate type owned, //< Non-temporary value passed by pointer @@ -2075,7 +1948,7 @@ type lval_maybe_callee = {bcx: block, val: ValueRef, kind: lval_kind, env: callee_env, - generic: generic_callee}; + tds: option<[ValueRef]>}; fn null_env_ptr(bcx: block) -> ValueRef { C_null(T_opaque_box_ptr(bcx.ccx())) @@ -2094,8 +1967,7 @@ 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, - generic: generic_none}; + ret {bcx: bcx, val: val, kind: kind, env: is_closure, tds: none}; } fn trans_external_path(cx: block, did: ast::def_id, @@ -2108,7 +1980,7 @@ fn trans_external_path(cx: block, did: ast::def_id, fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], vtables: option<typeck::vtable_res>) - -> option<{llfn: ValueRef, fty: ty::t}> { + -> option<ValueRef> { let substs = vec::map(substs, {|t| alt ty::get(t).struct { ty::ty_box(mt) { ty::mk_opaque_box(ccx.tcx) } @@ -2126,7 +1998,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], let tpt = ty::lookup_item_type(ccx.tcx, fn_id); let mono_ty = ty::substitute_type_params(ccx.tcx, substs, tpt.ty); - let llfty = type_of_fn_from_ty(ccx, mono_ty, []); + let llfty = type_of_fn_from_ty(ccx, mono_ty, 0u); let map_node = ccx.tcx.items.get(fn_id.node); // Get the path so that we can create a symbol @@ -2146,7 +2018,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], let pt = *pt + [path_name(ccx.names(name))]; let s = mangle_exported_name(ccx, pt, mono_ty); let lldecl = decl_cdecl_fn(ccx.llmod, s, llfty); - ccx.monomorphized.insert(hash_id, {llfn: lldecl, fty: mono_ty}); + ccx.monomorphized.insert(hash_id, lldecl); let psubsts = some({tys: substs, vtables: vtables, bounds: tpt.bounds}); alt check map_node { @@ -2182,10 +2054,9 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t], } } } - some({llfn: lldecl, fty: mono_ty}) + some(lldecl) } -// FIXME[mono] Only actually translate things that are not generic fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id) -> ast::def_id { alt ccx.external.find(fn_id) { @@ -2266,10 +2137,12 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id, } }; alt mono { - some({llfn, fty}) { - ret {bcx: bcx, val: llfn, + some(llfn) { + let cast = PointerCast(bcx, llfn, T_ptr(type_of_fn_from_ty( + ccx, node_id_type(bcx, id), 0u))); + ret {bcx: bcx, val: cast, kind: owned, env: null_env, - generic: generic_mono(fty)}; + tds: none}; } none {} } @@ -2295,23 +2168,22 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id, } } - let gen = generic_none, bcx = bcx; + let tds = none, bcx = bcx; + // FIXME[mono] ensure this is a native function if tys.len() > 0u { - let tydescs = [], tis = []; + 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, true, ti); - tis += [ti]; + let td = get_tydesc(bcx, t, ti); + lazily_emit_all_tydesc_glue(ccx, ti); bcx = td.bcx; tydescs += [td.val]; } - gen = generic_full({item_type: tpt.ty, - static_tis: tis, - tydescs: tydescs, - param_bounds: tpt.bounds, - origins: ccx.maps.vtable_map.find(id)}); + tds = some(tydescs); } - ret {bcx: bcx, val: val, kind: owned, env: null_env, generic: gen}; + ret {bcx: bcx, val: val, kind: owned, env: null_env, tds: tds}; } fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef { @@ -2564,7 +2436,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 = alt c.generic { generic_full(_) { true } _ { false } } || + let must_bind = option::is_some(c.tds) || alt c.env { self_env(_, _) { true } _ { false } }; if must_bind { let n_args = ty::ty_fn_args(ty).len(); @@ -2761,7 +2633,7 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr, // - new_fn_ctxt // - trans_args fn trans_args(cx: block, llenv: ValueRef, - gen: generic_callee, es: [@ast::expr], fn_ty: ty::t, + tds: option<[ValueRef]>, es: [@ast::expr], fn_ty: ty::t, dest: dest) -> {bcx: block, args: [ValueRef], @@ -2770,54 +2642,40 @@ fn trans_args(cx: block, llenv: ValueRef, let temp_cleanups = []; let args = ty::ty_fn_args(fn_ty); let llargs: [ValueRef] = []; - let lltydescs: [ValueRef] = []; let ccx = cx.ccx(); let bcx = cx; - let retty = ty::ty_fn_ret(fn_ty), full_retty = retty; - alt gen { - generic_full(g) { fail; } - generic_mono(t) { - args = ty::ty_fn_args(t); - retty = ty::ty_fn_ret(t); - } - _ { } - } + let retty = ty::ty_fn_ret(fn_ty); // Arg 0: Output pointer. let llretslot = alt dest { ignore { if ty::type_is_nil(retty) { llvm::LLVMGetUndef(T_ptr(T_nil())) } else { - let {bcx: cx, val} = alloc_ty(bcx, full_retty); + let {bcx: cx, val} = alloc_ty(bcx, retty); bcx = cx; val } } save_in(dst) { dst } by_val(_) { - let {bcx: cx, val} = alloc_ty(bcx, full_retty); + let {bcx: cx, val} = alloc_ty(bcx, retty); bcx = cx; val } }; - if retty != full_retty || ty::type_has_params(retty) { - // It's possible that the callee has some generic-ness somewhere in - // its return value -- say a method signature within an obj or a fn - // type deep in a structure -- which the caller has a concrete view - // of. If so, cast the caller's view of the restlot to the callee's - // view, for the sake of making a type-compatible call. - let llretty = T_ptr(type_of(ccx, retty)); - llargs += [PointerCast(cx, llretslot, llretty)]; - } else { llargs += [llretslot]; } + llargs += [llretslot]; // Arg 1: Env (closure-bindings / self value) llargs += [llenv]; // Args >2: ty_params ... - llargs += lltydescs; + alt tds { + some(tds) { llargs += tds; } + none {} + } // ... then explicit args. @@ -2883,7 +2741,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.generic, args, fn_expr_ty, dest); + trans_args(bcx, llenv, f_res.tds, args, fn_expr_ty, dest); bcx = args_res.bcx; let llargs = args_res.args; let llretslot = args_res.retslot; @@ -3418,7 +3276,7 @@ fn trans_log(lvl: @ast::expr, bcx: block, e: @ast::expr) -> block { with_scope(bcx, "log") {|bcx| let {bcx, val, _} = trans_temp_expr(bcx, e); let e_ty = expr_ty(bcx, e); - let {bcx, val: tydesc} = get_tydesc_simple(bcx, e_ty, false); + let {bcx, val: tydesc} = get_tydesc_simple(bcx, e_ty); // Call the polymorphic log function. let {bcx, val} = spill_if_immediate(bcx, val, e_ty); let val = PointerCast(bcx, val, T_ptr(T_i8())); @@ -4376,6 +4234,15 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) { let llfndecl = get_item_val(ccx, item.id); trans_fn(ccx, *path + [path_name(item.ident)], decl, body, llfndecl, no_self, none, item.id, none); + } else { + for stmt in body.node.stmts { + alt stmt.node { + ast::stmt_decl(@{node: ast::decl_item(i), _}, _) { + trans_item(ccx, *i); + } + _ {} + } + } } } ast::item_impl(tps, _, _, ms) { @@ -4400,8 +4267,8 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) { let vi = ty::enum_variants(ccx.tcx, local_def(item.id)); let i = 0; for variant: ast::variant in variants { - let llfn = get_item_val(ccx, variant.node.id); if variant.node.args.len() > 0u { + let llfn = get_item_val(ccx, variant.node.id); trans_enum_variant(ccx, item.id, variant, vi[i].disr_val, degen, none, llfn); @@ -4535,7 +4402,7 @@ 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); + let llfty = type_of_fn_from_ty(ccx, node_type, bnds.len()); register_fn_fuller(ccx, sp, path, flav, node_id, node_type, lib::llvm::CCallConv, llfty) } @@ -4582,7 +4449,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, []); + let llfty = type_of_fn(ccx, [vecarg_ty], nt, 0u); let llfdecl = decl_fn(ccx.llmod, "_rust_main", lib::llvm::CCallConv, llfty); diff --git a/src/rustc/middle/trans/closure.rs b/src/rustc/middle/trans/closure.rs index 2f5f6da87c2..eae89f4304c 100644 --- a/src/rustc/middle/trans/closure.rs +++ b/src/rustc/middle/trans/closure.rs @@ -131,21 +131,15 @@ 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: [fn_ty_param], + ty_params: option<[ValueRef]>, bound_values: [environment_value]) -> (ty::t, [ty::t]) { let bound_tys = []; - let tydesc_ty = mk_tydesc_ty(tcx, ck); - // Compute the closed over tydescs - let param_ptrs = []; - for tp in ty_params { - param_ptrs += [tydesc_ty]; - option::may(tp.vtables) {|vtables| - for vtable in vtables { param_ptrs += [tydesc_ty]; } - } - } + let n_param_ptrs = alt ty_params { + some(tds) { tds.len() } none { 0u } + }; // Compute the closed over data for bv in bound_values { @@ -158,7 +152,8 @@ fn mk_closure_tys(tcx: ty::ctxt, } let bound_data_ty = ty::mk_tup(tcx, bound_tys); - let cdata_ty = ty::mk_tup(tcx, [ty::mk_tup(tcx, param_ptrs), + 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), bound_data_ty]); #debug["cdata_ty=%s", ty_to_str(tcx, cdata_ty)]; ret (cdata_ty, bound_tys); @@ -186,7 +181,7 @@ fn allocate_cbox(bcx: block, &ti: option<@tydesc_info>) -> block { let ccx = bcx.ccx(); let bound_tydesc = GEPi(bcx, box, [0, abi::box_field_tydesc]); - let {bcx, val: td} = base::get_tydesc(bcx, cdata_ty, true, ti); + let {bcx, val: td} = base::get_tydesc(bcx, cdata_ty, ti); let td = Call(bcx, ccx.upcalls.create_shared_type_desc, [td]); Store(bcx, td, bound_tydesc); bcx @@ -243,7 +238,7 @@ fn cast_if_we_can(bcx: block, llbox: ValueRef, t: ty::t) -> ValueRef { // 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: [fn_ty_param], + bcx: block, lltyparams: option<[ValueRef]>, bound_values: [environment_value], ck: ty::closure_kind) -> closure_result { @@ -284,18 +279,11 @@ fn store_environment( let {bcx:bcx, val:ty_params_slot} = GEP_tup_like(bcx, cbox_ty, llbox, [0, abi::box_field_body, abi::closure_body_ty_params]); - let off = 0; - for tp in lltyparams { - let cloned_td = maybe_clone_tydesc(bcx, ck, tp.desc); - Store(bcx, cloned_td, GEPi(bcx, ty_params_slot, [0, off])); - off += 1; - option::may(tp.vtables, {|vtables| - for vtable in vtables { - let cast = PointerCast(bcx, vtable, val_ty(cloned_td)); - Store(bcx, cast, GEPi(bcx, ty_params_slot, [0, off])); - off += 1; - } - }); + 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. @@ -389,14 +377,13 @@ fn build_closure(bcx0: block, } } } - ret store_environment(bcx, copy bcx.fcx.lltyparams, env_vals, ck); + ret store_environment(bcx, none, env_vals, ck); } // Given an enclosing block context, a new function context, a closure type, // and a list of upvars, generate code to load and populate the environment // with the upvars and type descriptors. -fn load_environment(enclosing_cx: block, - fcx: fn_ctxt, +fn load_environment(fcx: fn_ctxt, cdata_ty: ty::t, cap_vars: [capture::capture_var], ck: ty::closure_kind) { @@ -405,27 +392,6 @@ fn load_environment(enclosing_cx: block, // Load a pointer to the closure data, skipping over the box header: let llcdata = base::opaque_box_body(bcx, cdata_ty, fcx.llenv); - // Populate the type parameters from the environment. We need to - // do this first because the tydescs are needed to index into - // the bindings if they are dynamically sized. - let {bcx, val: lltydescs} = GEP_tup_like(bcx, cdata_ty, llcdata, - [0, abi::closure_body_ty_params]); - let off = 0; - for tp in copy enclosing_cx.fcx.lltyparams { - let tydesc = Load(bcx, GEPi(bcx, lltydescs, [0, off])); - off += 1; - let vtables = option::map(tp.vtables, {|vtables| - let rslt = []; - for vtable in vtables { - let vtable = Load(bcx, GEPi(bcx, lltydescs, [0, off])); - rslt += [PointerCast(bcx, vtable, T_ptr(T_vtable()))]; - off += 1; - } - rslt - }); - fcx.lltyparams += [{desc: tydesc, vtables: vtables}]; - } - // Populate the upvars from the environment. let i = 0u; vec::iter(cap_vars) { |cap_var| @@ -460,7 +426,7 @@ 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, []); + let llfnty = type_of_fn_from_ty(ccx, fty, 0u); 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); @@ -472,7 +438,7 @@ fn trans_expr_fn(bcx: block, let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, ck, id); trans_closure(ccx, sub_path, decl, body, llfn, no_self, bcx.fcx.param_substs, id, none, {|fcx| - load_environment(bcx, fcx, cdata_ty, cap_vars, ck); + load_environment(fcx, cdata_ty, cap_vars, ck); }); llbox }; @@ -513,13 +479,7 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t, ret bcx; } - // Figure out which tydescs we need to pass, if any. - let (outgoing_fty_real, lltydescs, param_bounds) = alt f_res.generic { - generic_full(ginfo) { fail; } - _ { (outgoing_fty, [], @[]) } - }; - - if bound.len() == 0u && lltydescs.len() == 0u && + if bound.len() == 0u && option::is_none(f_res.tds) && (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); @@ -545,14 +505,15 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t, // Actually construct the closure let {llbox, cdata_ty, bcx} = store_environment( - bcx, vec::map(lltydescs, {|d| {desc: d, vtables: none}}), + bcx, f_res.tds, 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_real, args, - cdata_ty, *param_bounds, target_info); + cx.fcx.ccx, cx.fcx.path, pair_ty, outgoing_fty, args, + cdata_ty, target_info, + alt f_res.tds { some(x) { x.len() } _ { 0u } }); // Fill the function pair fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, llbox); @@ -704,16 +665,15 @@ fn trans_bind_thunk(ccx: @crate_ctxt, outgoing_fty: ty::t, args: [option<@ast::expr>], cdata_ty: ty::t, - param_bounds: [ty::param_bounds], - target_info: target_info) + target_info: target_info, + n_tps: uint) -> {val: ValueRef, ty: TypeRef} { let tcx = ccx.tcx; #debug["trans_bind_thunk[incoming_fty=%s,outgoing_fty=%s,\ - cdata_ty=%s,param_bounds=%?]", + cdata_ty=%s]", ty_to_str(tcx, incoming_fty), ty_to_str(tcx, outgoing_fty), - ty_to_str(tcx, cdata_ty), - param_bounds]; + ty_to_str(tcx, cdata_ty)]; // Here we're not necessarily constructing a thunk in the sense of // "function with no arguments". The result of compiling 'bind f(foo, @@ -813,28 +773,11 @@ fn trans_bind_thunk(ccx: @crate_ctxt, let {bcx: l_bcx, val: param_record} = GEP_tup_like(l_bcx, cdata_ty, llcdata, [0, abi::closure_body_ty_params]); - let off = 0; - for param in param_bounds { - let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, off])), - vtables = none; + let i = 0u; + while i < n_tps { + let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, i as int])); llargs += [dsc]; - off += 1; - for bound in *param { - alt bound { - ty::bound_iface(_) { - let vtable = Load(l_bcx, GEPi(l_bcx, param_record, [0, off])); - vtable = PointerCast(l_bcx, vtable, T_ptr(T_vtable())); - llargs += [vtable]; - off += 1; - vtables = some(alt vtables { - none { [vtable] } - some(ds) { ds + [vtable] } - }); - } - _ {} - } - } - fcx.lltyparams += [{desc: dsc, vtables: vtables}]; + fcx.lltyparams += [{desc: dsc, vtables: none}]; } let a: uint = first_tp_arg; // retptr, env come first @@ -895,7 +838,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, param_bounds); + type_of_fn_from_ty(ccx, outgoing_fty, 0u); 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 7dce92d94d7..6c7b1aa916f 100644 --- a/src/rustc/middle/trans/common.rs +++ b/src/rustc/middle/trans/common.rs @@ -93,7 +93,7 @@ type crate_ctxt = { // Track mapping of external ids to local items imported for inlining external: hashmap<ast::def_id, option<ast::node_id>>, // Cache instances of monomorphized functions - monomorphized: hashmap<mono_id, {llfn: ValueRef, fty: ty::t}>, + monomorphized: hashmap<mono_id, ValueRef>, // Cache generated vtables vtables: hashmap<mono_id, ValueRef>, module_data: hashmap<str, ValueRef>, @@ -180,6 +180,7 @@ type fn_ctxt = @{ llupvars: hashmap<ast::node_id, ValueRef>, // A vector of incoming type descriptors and their associated vtables. + // Currently only used by glue functions mutable lltyparams: [fn_ty_param], // Derived tydescs are tydescs created at runtime, for types that @@ -307,7 +308,7 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, inner_t: ty::t) let nil_res = ty::mk_nil(ccx.tcx); let fn_mode = ast::expl(ast::by_ref); let f_t = type_of::type_of_fn(ccx, [{mode: fn_mode, ty: inner_t}], - nil_res, *param_bounds); + nil_res, (*param_bounds).len()); ret base::get_extern_const(ccx.externs, ccx.llmod, csearch::get_symbol(ccx.sess.cstore, did), f_t); @@ -542,9 +543,9 @@ fn set_struct_body(t: TypeRef, elts: [TypeRef]) unsafe { fn T_empty_struct() -> TypeRef { ret T_struct([]); } // A vtable is, in reality, a vtable pointer followed by zero or more pointers -// to tydescs and other vtables that it closes over. But the types and number -// of those are rarely known to the code that needs to manipulate them, so -// they are described by this opaque type. +// to tydescs and other vtables that it closes over. But the types and number of +// those are rarely known to the code that needs to manipulate them, so they +// are described by this opaque type. fn T_vtable() -> TypeRef { T_array(T_ptr(T_i8()), 1u) } fn T_task(targ_cfg: @session::config) -> TypeRef { diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index a48f4147ba3..85ba984bed9 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -76,7 +76,7 @@ fn trans_static_callee(bcx: block, callee_id: ast::node_id, 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); + 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)} } @@ -86,13 +86,11 @@ fn trans_vtable_callee(bcx: block, env: callee_env, vtable: ValueRef, -> 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, []); + let llfty = type_of::type_of_fn_from_ty(ccx, fty, 0u); 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, - generic: generic_none} + {bcx: bcx, val: mptr, kind: owned, env: env, tds: none} } fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id, @@ -243,10 +241,10 @@ 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, [])) + C_null(type_of_fn_from_ty(ccx, fty, 0u)) } else { let m_id = method_with_name(ccx, impl_id, im.ident); - option::get(monomorphic_fn(ccx, m_id, substs, some(vtables))).llfn + option::get(monomorphic_fn(ccx, m_id, substs, some(vtables))) } })) } diff --git a/src/rustc/middle/trans/native.rs b/src/rustc/middle/trans/native.rs index 3a681644f51..7aa059fb17e 100644 --- a/src/rustc/middle/trans/native.rs +++ b/src/rustc/middle/trans/native.rs @@ -269,7 +269,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, []); + let llty = type_of_fn_from_ty(ccx, t, 0u); let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty); trans_fn(ccx, path, decl, body, llfndecl, no_self, none, id, none); @@ -383,8 +383,7 @@ fn decl_native_fn(ccx: @crate_ctxt, i: @ast::native_item, 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, param_bounds(ccx, tps)); + let fn_type = type_of_fn_from_ty(ccx, node_type, tps.len()); 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, diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs index 0502fc9abb1..cf774e19acf 100644 --- a/src/rustc/middle/trans/shape.rs +++ b/src/rustc/middle/trans/shape.rs @@ -701,7 +701,7 @@ fn dynamic_metrics(cx: block, t: ty::t) -> metrics { alt ty::get(t).struct { ty::ty_param(p, _) { - let {bcx, val: tydesc} = base::get_tydesc_simple(cx, t, false); + let {bcx, val: tydesc} = base::get_tydesc_simple(cx, t); let szptr = GEPi(bcx, tydesc, [0, abi::tydesc_field_size]); let aptr = GEPi(bcx, tydesc, [0, abi::tydesc_field_align]); {bcx: bcx, sz: Load(bcx, szptr), align: Load(bcx, aptr)} diff --git a/src/rustc/middle/trans/tvec.rs b/src/rustc/middle/trans/tvec.rs index aeaf65db7f4..e7034adb47d 100644 --- a/src/rustc/middle/trans/tvec.rs +++ b/src/rustc/middle/trans/tvec.rs @@ -202,7 +202,7 @@ fn trans_append_literal(bcx: block, vptrptr: ValueRef, vec_ty: ty::t, let ccx = bcx.ccx(); let elt_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); let ti = none; - let {bcx: bcx, val: td} = get_tydesc(bcx, elt_ty, false, ti); + let {bcx: bcx, val: td} = get_tydesc(bcx, elt_ty, ti); base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, ti); let opaque_v = PointerCast(bcx, vptrptr, T_ptr(T_ptr(ccx.opaque_vec_type))); diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs index 417147fee95..a7991563abb 100644 --- a/src/rustc/middle/trans/type_of.rs +++ b/src/rustc/middle/trans/type_of.rs @@ -19,7 +19,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, params: [ty::param_bounds]) -> TypeRef { + output: ty::t, n_ty_params: uint) -> TypeRef { let atys: [TypeRef] = []; // Arg 0: Output pointer. @@ -29,14 +29,10 @@ fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg], atys += [T_opaque_box_ptr(cx)]; // Args >2: ty params, if not acquired via capture... - for bounds in params { + let i = 0u; + while i < n_ty_params { atys += [T_ptr(cx.tydesc_type)]; - for bound in *bounds { - alt bound { - ty::bound_iface(_) { atys += [T_ptr(T_vtable())]; } - _ {} - } - } + i += 1u; } // ... then explicit args. atys += type_of_explicit_args(cx, inputs); @@ -44,9 +40,9 @@ fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg], } // 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, - param_bounds: [ty::param_bounds]) -> TypeRef { - type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty), param_bounds) +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(cx: @crate_ctxt, t: ty::t) -> TypeRef { @@ -93,7 +89,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, [])) + T_fn_pair(cx, type_of_fn_from_ty(cx, t, 0u)) } ty::ty_iface(_, _) { T_opaque_iface(cx) } ty::ty_res(_, sub, tps) { @@ -155,7 +151,7 @@ fn type_of_ty_param_bounds_and_ty let t = tpt.ty; alt ty::get(t).struct { ty::ty_fn(_) { - ret type_of_fn_from_ty(ccx, t, *tpt.bounds); + ret type_of_fn_from_ty(ccx, t, (*tpt.bounds).len()); } _ { // fall through |
