Skip to content

Commit cedecf9

Browse files
committed
---
yaml --- r: 12787 b: refs/heads/master c: e12b16c h: refs/heads/master i: 12785: 1ed0c8f 12783: 18d8d9c v: v3
1 parent f3b0f33 commit cedecf9

File tree

7 files changed

+162
-61
lines changed

7 files changed

+162
-61
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 97aba0b14f965059a18f8e5ef8138dcfd5fe6293
2+
refs/heads/master: e12b16cde7ecc4075a105f4e4b128f63c0c03c8d
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/rustc/back/abi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const tydesc_field_align: uint = 2u;
3939
const tydesc_field_take_glue: uint = 3u;
4040
const tydesc_field_drop_glue: uint = 4u;
4141
const tydesc_field_free_glue: uint = 5u;
42-
const tydesc_field_unused: uint = 6u;
42+
const tydesc_field_visit_glue: uint = 6u;
4343
const tydesc_field_sever_glue: uint = 7u;
4444
const tydesc_field_mark_glue: uint = 8u;
4545
const tydesc_field_unused2: uint = 9u;

trunk/src/rustc/middle/trans/base.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,8 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
470470
align: llalign,
471471
mut take_glue: none,
472472
mut drop_glue: none,
473-
mut free_glue: none};
473+
mut free_glue: none,
474+
mut visit_glue: none};
474475
log(debug, "--- declare_tydesc " + ty_to_str(ccx.tcx, t));
475476
ret inf;
476477
}
@@ -552,6 +553,11 @@ fn emit_tydescs(ccx: @crate_ctxt) {
552553
none { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
553554
some(v) { ccx.stats.n_real_glues += 1u; v }
554555
};
556+
let visit_glue =
557+
alt ti.visit_glue {
558+
none { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
559+
some(v) { ccx.stats.n_real_glues += 1u; v }
560+
};
555561

556562
let shape = shape_of(ccx, key, []);
557563
let shape_tables =
@@ -566,7 +572,7 @@ fn emit_tydescs(ccx: @crate_ctxt) {
566572
take_glue, // take_glue
567573
drop_glue, // drop_glue
568574
free_glue, // free_glue
569-
C_null(T_ptr(T_i8())), // unused
575+
visit_glue, // visit_glue
570576
C_null(glue_fn_ty), // sever_glue
571577
C_null(glue_fn_ty), // mark_glue
572578
C_null(glue_fn_ty), // unused
@@ -632,6 +638,20 @@ fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) {
632638
Store(cx, rc, rc_ptr);
633639
}
634640

641+
fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) {
642+
let _icx = bcx.insn_ctxt("make_visit_glue");
643+
let mut bcx = bcx;
644+
alt bcx.ccx().intrinsic_ifaces.find("visit_ty") {
645+
some(iid) {
646+
bcx = reflect::emit_calls_to_iface_visit_ty(bcx, t, v, iid);
647+
}
648+
none {
649+
}
650+
}
651+
build_return(bcx);
652+
}
653+
654+
635655
fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
636656
// v is a pointer to the actual box component of the type here. The
637657
// ValueRef will have the wrong type here (make_generic_glue is casting
@@ -1065,7 +1085,23 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
10651085
ty_to_str(ccx.tcx, ti.ty));
10661086
}
10671087
}
1088+
} else if field == abi::tydesc_field_visit_glue {
1089+
alt ti.free_glue {
1090+
some(_) { }
1091+
none {
1092+
#debug("+++ lazily_emit_tydesc_glue VISIT %s",
1093+
ty_to_str(ccx.tcx, ti.ty));
1094+
let glue_fn =
1095+
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "visit");
1096+
ti.visit_glue = some(glue_fn);
1097+
make_generic_glue(ccx, ti.ty, glue_fn,
1098+
make_visit_glue, "visit");
1099+
#debug("--- lazily_emit_tydesc_glue VISIT %s",
1100+
ty_to_str(ccx.tcx, ti.ty));
1101+
}
1102+
}
10681103
}
1104+
10691105
}
10701106
}
10711107
}
@@ -5056,6 +5092,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
50565092
tn: tn,
50575093
externs: str_hash::<ValueRef>(),
50585094
intrinsics: intrinsics,
5095+
intrinsic_ifaces: reflect::find_intrinsic_ifaces(crate),
50595096
item_vals: int_hash::<ValueRef>(),
50605097
exp_map: emap,
50615098
reachable: reachable,

trunk/src/rustc/middle/trans/common.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ type tydesc_info =
3333
align: ValueRef,
3434
mut take_glue: option<ValueRef>,
3535
mut drop_glue: option<ValueRef>,
36-
mut free_glue: option<ValueRef>};
36+
mut free_glue: option<ValueRef>,
37+
mut visit_glue: option<ValueRef>};
3738

3839
/*
3940
* A note on nomenclature of linking: "upcall", "extern" and "native".
@@ -70,6 +71,7 @@ type crate_ctxt = {
7071
tn: type_names,
7172
externs: hashmap<str, ValueRef>,
7273
intrinsics: hashmap<str, ValueRef>,
74+
intrinsic_ifaces: hashmap<str, ast::def_id>,
7375
item_vals: hashmap<ast::node_id, ValueRef>,
7476
exp_map: resolve::exp_map,
7577
reachable: reachable::map,
@@ -572,8 +574,8 @@ fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
572574
let int_type = T_int(targ_cfg);
573575
let elems =
574576
[tydescpp, int_type, int_type,
575-
glue_fn_ty, glue_fn_ty, glue_fn_ty,
576-
T_ptr(T_i8()), glue_fn_ty, glue_fn_ty, glue_fn_ty, T_ptr(T_i8()),
577+
glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty,
578+
glue_fn_ty, glue_fn_ty, glue_fn_ty, T_ptr(T_i8()),
577579
T_ptr(T_i8()), T_ptr(T_i8()), int_type, int_type];
578580
set_struct_body(tydesc, elems);
579581
ret tydesc;

trunk/src/rustc/middle/trans/native.rs

Lines changed: 22 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -835,70 +835,38 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
835835
fcx.llretptr);
836836
}
837837
"visit_ty" {
838-
839-
// signature: fn visit_ty<T,V:ty_visitor>(tv: V);
840-
841838
let tp_ty = substs.tys[0];
842839
let vp_ty = substs.tys[1];
843840
let visitor = get_param(decl, first_real_arg);
844841

845-
let (tyname, args) = alt ty::get(tp_ty).struct {
846-
ty::ty_bot { ("bot", []) }
847-
ty::ty_nil { ("nil", []) }
848-
ty::ty_bool { ("bool", []) }
849-
ty::ty_int(ast::ty_i) { ("int", []) }
850-
ty::ty_int(ast::ty_char) { ("char", []) }
851-
ty::ty_int(ast::ty_i8) { ("i8", []) }
852-
ty::ty_int(ast::ty_i16) { ("i16", []) }
853-
ty::ty_int(ast::ty_i32) { ("i32", []) }
854-
ty::ty_int(ast::ty_i64) { ("i64", []) }
855-
ty::ty_uint(ast::ty_u) { ("uint", []) }
856-
ty::ty_uint(ast::ty_u8) { ("u8", []) }
857-
ty::ty_uint(ast::ty_u16) { ("u16", []) }
858-
ty::ty_uint(ast::ty_u32) { ("u32", []) }
859-
ty::ty_uint(ast::ty_u64) { ("u64", []) }
860-
ty::ty_float(ast::ty_f) { ("float", []) }
861-
ty::ty_float(ast::ty_f32) { ("f32", []) }
862-
ty::ty_float(ast::ty_f64) { ("f64", []) }
863-
ty::ty_str { ("str", []) }
864-
_ {
865-
bcx.sess().unimpl("trans::native::visit_ty on "
866-
+ ty_to_str(ccx.tcx, tp_ty));
867-
}
868-
};
869-
870-
let mth_name = "visit_" + tyname;
871-
let dest = ignore;
872-
873842
alt impl::find_vtable_in_fn_ctxt(substs,
874843
1u, /* n_param */
875844
0u /* n_bound */ ) {
876845

877-
typeck::vtable_static(impl_did, impl_substs, sub_origins) {
878-
let mth_id = impl::method_with_name(ccx, impl_did, mth_name);
879-
let mth_ty = ty::lookup_item_type(ccx.tcx, mth_id).ty;
880-
// FIXME: is this safe? There is no callee AST node,
881-
// we're synthesizing it.
882-
let callee_id = (-1) as ast::node_id;
883-
let get_lval = {|bcx|
884-
let lval = lval_static_fn_inner(bcx, mth_id, callee_id,
885-
impl_substs,
886-
some(sub_origins));
887-
{env: self_env(visitor, vp_ty, none) with lval}
888-
};
889-
bcx = trans_call_inner(bcx, mth_ty, ty::mk_bool(ccx.tcx),
890-
get_lval, arg_vals(args), dest);
846+
typeck::vtable_iface(iid, _) {
847+
bcx = reflect::emit_calls_to_iface_visit_ty(bcx, tp_ty,
848+
visitor, iid);
891849
}
892850

893-
typeck::vtable_iface(iid, _tps) {
894-
let methods = ty::iface_methods(ccx.tcx, iid);
895-
let mth_idx = option::get(ty::method_idx(mth_name, *methods));
896-
let mth_ty = ty::mk_fn(ccx.tcx, methods[mth_idx].fty);
897-
let get_lval = {|bcx|
898-
impl::trans_iface_callee(bcx, visitor, mth_ty, mth_idx)
899-
};
900-
bcx = trans_call_inner(bcx, mth_ty, ty::mk_bool(ccx.tcx),
901-
get_lval, arg_vals(args), dest);
851+
// This case is a slightly weird and possibly redundant path in
852+
// which we monomorphize the reflection interface. FIXME:
853+
// possibly remove this, it might be overkill.
854+
typeck::vtable_static(impl_did, impl_substs, sub_origins) {
855+
reflect::visit_ty_steps(bcx, tp_ty) {|mth_name, args|
856+
let mth_id = impl::method_with_name(ccx, impl_did, mth_name);
857+
let mth_ty = ty::lookup_item_type(ccx.tcx, mth_id).ty;
858+
// FIXME: is this safe? There is no callee AST node,
859+
// we're synthesizing it.
860+
let callee_id = (-1) as ast::node_id;
861+
let get_lval = {|bcx|
862+
let lval = lval_static_fn_inner(bcx, mth_id, callee_id,
863+
impl_substs,
864+
some(sub_origins));
865+
{env: self_env(visitor, vp_ty, none) with lval}
866+
};
867+
bcx = trans_call_inner(bcx, mth_ty, ty::mk_bool(ccx.tcx),
868+
get_lval, arg_vals(args), ignore);
869+
}
902870
}
903871

904872
_ {
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import std::map::{hashmap,str_hash};
2+
import driver::session::session;
3+
import lib::llvm::{TypeRef, ValueRef};
4+
import syntax::ast;
5+
import back::abi;
6+
import common::*;
7+
import build::*;
8+
import base::*;
9+
import type_of::*;
10+
import ast::def_id;
11+
import util::ppaux::ty_to_str;
12+
13+
fn visit_ty_steps<T>(bcx: block, t: ty::t,
14+
step: fn(tyname: str, args: [ValueRef]) -> T) -> T {
15+
alt ty::get(t).struct {
16+
ty::ty_bot { step("visit_bot", []) }
17+
ty::ty_nil { step("visit_nil", []) }
18+
ty::ty_bool { step("visit_bool", []) }
19+
ty::ty_int(ast::ty_i) { step("visit_int", []) }
20+
ty::ty_int(ast::ty_char) { step("visit_char", []) }
21+
ty::ty_int(ast::ty_i8) { step("visit_i8", []) }
22+
ty::ty_int(ast::ty_i16) { step("visit_i16", []) }
23+
ty::ty_int(ast::ty_i32) { step("visit_i32", []) }
24+
ty::ty_int(ast::ty_i64) { step("visit_i64", []) }
25+
ty::ty_uint(ast::ty_u) { step("visit_uint", []) }
26+
ty::ty_uint(ast::ty_u8) { step("visit_u8", []) }
27+
ty::ty_uint(ast::ty_u16) { step("visit_u16", []) }
28+
ty::ty_uint(ast::ty_u32) { step("visit_u32", []) }
29+
ty::ty_uint(ast::ty_u64) { step("visit_u64", []) }
30+
ty::ty_float(ast::ty_f) { step("visit_float", []) }
31+
ty::ty_float(ast::ty_f32) { step("visit_f32", []) }
32+
ty::ty_float(ast::ty_f64) { step("visit_f64", []) }
33+
ty::ty_str { step("visit_str", []) }
34+
_ {
35+
bcx.sess().unimpl("trans::reflect::visit_ty_args on "
36+
+ ty_to_str(bcx.ccx().tcx, t));
37+
}
38+
}
39+
}
40+
41+
// Emit a sequence of calls to visit_ty::visit_foo
42+
fn emit_calls_to_iface_visit_ty(bcx: block, t: ty::t,
43+
visitor_val: ValueRef,
44+
visitor_iid: def_id) -> block {
45+
let tcx = bcx.tcx();
46+
visit_ty_steps(bcx, t) {|mth_name, args|
47+
let methods = ty::iface_methods(tcx, visitor_iid);
48+
let mth_idx = option::get(ty::method_idx(mth_name, *methods));
49+
let mth_ty = ty::mk_fn(tcx, methods[mth_idx].fty);
50+
let get_lval = {|bcx|
51+
impl::trans_iface_callee(bcx, visitor_val, mth_ty, mth_idx)
52+
};
53+
trans_call_inner(bcx, mth_ty, ty::mk_bool(tcx),
54+
get_lval, arg_vals(args), ignore)
55+
}
56+
}
57+
58+
59+
fn find_intrinsic_ifaces(crate: @ast::crate)
60+
-> hashmap<str, ast::def_id> {
61+
62+
let ifaces : hashmap<str, ast::def_id> = str_hash();
63+
64+
// FIXME: hooking into the "intrinsic" root module is crude.
65+
// there ought to be a better approach. Attributes?
66+
67+
for crate.node.module.items.each {|crate_item|
68+
if crate_item.ident == "intrinsic" {
69+
alt crate_item.node {
70+
ast::item_mod(m) {
71+
for m.items.each {|intrinsic_item|
72+
alt intrinsic_item.node {
73+
ast::item_iface(_, _, _) {
74+
let def_id = { crate: ast::local_crate,
75+
node: intrinsic_item.id };
76+
ifaces.insert(intrinsic_item.ident,
77+
def_id);
78+
}
79+
_ { }
80+
}
81+
}
82+
}
83+
_ { }
84+
}
85+
break;
86+
}
87+
}
88+
89+
// Assert whatever ifaces we are expecting to get from mod intrinsic.
90+
// assert ifaces.contains_key("visit_ty");
91+
92+
ret ifaces;
93+
}

trunk/src/rustc/rustc.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ mod middle {
4242
mod tvec;
4343
mod impl;
4444
mod native;
45+
mod reflect;
4546
mod shape;
4647
mod debuginfo;
4748
mod type_use;

0 commit comments

Comments
 (0)