Modify reflect interface to pass tydescs back to client, stop on false return.
These changes are required to prune type-recursion and admit early returns in the visitor code. Changes to visitors in subsequent csets.
This commit is contained in:
parent
ef9a64709e
commit
0a4a602a23
@ -3,8 +3,21 @@
|
||||
|
||||
mod intrinsic {
|
||||
|
||||
import rusti::visit_ty;
|
||||
export ty_visitor, visit_ty;
|
||||
import rusti::visit_tydesc;
|
||||
export ty_visitor, get_tydesc, visit_tydesc, tydesc;
|
||||
|
||||
// FIXME (#2712): remove this when the interface has settled and the
|
||||
// version in sys is no longer present.
|
||||
fn get_tydesc<T>() -> *tydesc {
|
||||
rusti::get_tydesc::<T>() as *tydesc
|
||||
}
|
||||
|
||||
enum tydesc = {
|
||||
first_param: **u8,
|
||||
size: uint,
|
||||
align: uint
|
||||
// Remaining fields not listed
|
||||
};
|
||||
|
||||
iface ty_visitor {
|
||||
fn visit_bot() -> bool;
|
||||
@ -35,50 +48,37 @@ mod intrinsic {
|
||||
fn visit_estr_slice() -> bool;
|
||||
fn visit_estr_fixed(sz: uint) -> bool;
|
||||
|
||||
fn visit_enter_box(mtbl: uint) -> bool;
|
||||
fn visit_leave_box(mtbl: uint) -> bool;
|
||||
fn visit_enter_uniq(mtbl: uint) -> bool;
|
||||
fn visit_leave_uniq(mtbl: uint) -> bool;
|
||||
fn visit_enter_ptr(mtbl: uint) -> bool;
|
||||
fn visit_leave_ptr(mtbl: uint) -> bool;
|
||||
fn visit_enter_rptr(mtbl: uint) -> bool;
|
||||
fn visit_leave_rptr(mtbl: uint) -> bool;
|
||||
fn visit_box(mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_uniq(mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_ptr(mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_rptr(mtbl: uint, inner: *tydesc) -> bool;
|
||||
|
||||
fn visit_enter_vec(mtbl: uint) -> bool;
|
||||
fn visit_leave_vec(mtbl: uint) -> bool;
|
||||
fn visit_enter_evec_box(mtbl: uint) -> bool;
|
||||
fn visit_leave_evec_box(mtbl: uint) -> bool;
|
||||
fn visit_enter_evec_uniq(mtbl: uint) -> bool;
|
||||
fn visit_leave_evec_uniq(mtbl: uint) -> bool;
|
||||
fn visit_enter_evec_slice(mtbl: uint) -> bool;
|
||||
fn visit_leave_evec_slice(mtbl: uint) -> bool;
|
||||
fn visit_enter_evec_fixed(mtbl: uint, n: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_leave_evec_fixed(mtbl: uint, n: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_vec(mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_unboxed_vec(mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_evec_box(mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_evec_uniq(mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_evec_slice(mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_evec_fixed(n: uint, mtbl: uint,
|
||||
sz: uint, align: uint,
|
||||
inner: *tydesc) -> bool;
|
||||
|
||||
fn visit_enter_rec(n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_enter_rec_field(mtbl: uint, i: uint,
|
||||
name: str/&) -> bool;
|
||||
fn visit_leave_rec_field(mtbl: uint, i: uint,
|
||||
name: str/&) -> bool;
|
||||
fn visit_rec_field(i: uint, name: str/&,
|
||||
mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_leave_rec(n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_class(n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_enter_class_field(mtbl: uint, i: uint,
|
||||
name: str/&) -> bool;
|
||||
fn visit_leave_class_field(mtbl: uint, i: uint,
|
||||
name: str/&) -> bool;
|
||||
fn visit_class_field(i: uint, name: str/&,
|
||||
mtbl: uint, inner: *tydesc) -> bool;
|
||||
fn visit_leave_class(n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_tup(n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_enter_tup_field(i: uint) -> bool;
|
||||
fn visit_leave_tup_field(i: uint) -> bool;
|
||||
fn visit_tup_field(i: uint, inner: *tydesc) -> bool;
|
||||
fn visit_leave_tup(n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
@ -88,8 +88,7 @@ mod intrinsic {
|
||||
disr_val: int,
|
||||
n_fields: uint,
|
||||
name: str/&) -> bool;
|
||||
fn visit_enter_enum_variant_field(i: uint) -> bool;
|
||||
fn visit_leave_enum_variant_field(i: uint) -> bool;
|
||||
fn visit_enum_variant_field(i: uint, inner: *tydesc) -> bool;
|
||||
fn visit_leave_enum_variant(variant: uint,
|
||||
disr_val: int,
|
||||
n_fields: uint,
|
||||
@ -99,29 +98,25 @@ mod intrinsic {
|
||||
|
||||
fn visit_enter_fn(purity: uint, proto: uint,
|
||||
n_inputs: uint, retstyle: uint) -> bool;
|
||||
fn visit_enter_fn_input(i: uint, mode: uint) -> bool;
|
||||
fn visit_leave_fn_input(i: uint, mode: uint) -> bool;
|
||||
fn visit_enter_fn_output(retstyle: uint) -> bool;
|
||||
fn visit_leave_fn_output(retstyle: uint) -> bool;
|
||||
fn visit_fn_input(i: uint, mode: uint, inner: *tydesc) -> bool;
|
||||
fn visit_fn_output(retstyle: uint, inner: *tydesc) -> bool;
|
||||
fn visit_leave_fn(purity: uint, proto: uint,
|
||||
n_inputs: uint, retstyle: uint) -> bool;
|
||||
|
||||
fn visit_trait() -> bool;
|
||||
fn visit_enter_res() -> bool;
|
||||
fn visit_leave_res() -> bool;
|
||||
fn visit_var() -> bool;
|
||||
fn visit_var_integral() -> bool;
|
||||
fn visit_param(i: uint) -> bool;
|
||||
fn visit_self() -> bool;
|
||||
fn visit_type() -> bool;
|
||||
fn visit_opaque_box() -> bool;
|
||||
fn visit_enter_constr() -> bool;
|
||||
fn visit_leave_constr() -> bool;
|
||||
fn visit_constr(inner: *tydesc) -> bool;
|
||||
fn visit_closure_ptr(ck: uint) -> bool;
|
||||
}
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern mod rusti {
|
||||
fn visit_ty<T>(&&tv: ty_visitor);
|
||||
fn get_tydesc<T>() -> *();
|
||||
fn visit_tydesc(td: *tydesc, &&tv: ty_visitor);
|
||||
}
|
||||
}
|
||||
|
@ -671,8 +671,8 @@ fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) {
|
||||
fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) {
|
||||
let _icx = bcx.insn_ctxt("make_visit_glue");
|
||||
let mut bcx = bcx;
|
||||
assert bcx.ccx().tcx.intrinsic_traits.contains_key(@"ty_visitor");
|
||||
let (iid, ty) = bcx.ccx().tcx.intrinsic_traits.get(@"ty_visitor");
|
||||
assert bcx.ccx().tcx.intrinsic_defs.contains_key(@"ty_visitor");
|
||||
let (iid, ty) = bcx.ccx().tcx.intrinsic_defs.get(@"ty_visitor");
|
||||
let v = PointerCast(bcx, v, T_ptr(type_of::type_of(bcx.ccx(), ty)));
|
||||
bcx = reflect::emit_calls_to_trait_visit_ty(bcx, t, v, iid);
|
||||
build_return(bcx);
|
||||
|
@ -910,8 +910,13 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
||||
}
|
||||
"get_tydesc" {
|
||||
let tp_ty = substs.tys[0];
|
||||
let td = get_tydesc_simple(ccx, tp_ty);
|
||||
Store(bcx, PointerCast(bcx, td, T_ptr(T_nil())), fcx.llretptr);
|
||||
let mut static_ti = none;
|
||||
let lltydesc = get_tydesc(ccx, tp_ty, static_ti);
|
||||
lazily_emit_all_tydesc_glue(ccx, copy static_ti);
|
||||
// FIXME (#2712): change this to T_ptr(ccx.tydesc_ty) when the
|
||||
// core::sys copy of the get_tydesc interface dies off.
|
||||
let td = PointerCast(bcx, lltydesc, T_ptr(T_nil()));
|
||||
Store(bcx, td, fcx.llretptr);
|
||||
}
|
||||
"init" {
|
||||
let tp_ty = substs.tys[0];
|
||||
@ -951,10 +956,12 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
||||
Store(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)),
|
||||
fcx.llretptr);
|
||||
}
|
||||
"visit_ty" {
|
||||
let tp_ty = substs.tys[0];
|
||||
let visitor = get_param(decl, first_real_arg);
|
||||
call_tydesc_glue(bcx, visitor, tp_ty, abi::tydesc_field_visit_glue);
|
||||
"visit_tydesc" {
|
||||
let td = get_param(decl, first_real_arg);
|
||||
let visitor = get_param(decl, first_real_arg + 1u);
|
||||
let td = PointerCast(bcx, td, T_ptr(ccx.tydesc_type));
|
||||
call_tydesc_glue_full(bcx, visitor, td,
|
||||
abi::tydesc_field_visit_glue, none);
|
||||
}
|
||||
"frame_address" {
|
||||
let frameaddress = ccx.intrinsics.get("llvm.frameaddress");
|
||||
|
@ -13,6 +13,8 @@ import util::ppaux::ty_to_str;
|
||||
enum reflector = {
|
||||
visitor_val: ValueRef,
|
||||
visitor_methods: @~[ty::method],
|
||||
final_bcx: block,
|
||||
tydesc_ty: TypeRef,
|
||||
mut bcx: block
|
||||
};
|
||||
|
||||
@ -39,6 +41,19 @@ impl methods for reflector {
|
||||
self.c_uint(a)];
|
||||
}
|
||||
|
||||
fn c_tydesc(t: ty::t) -> ValueRef {
|
||||
let bcx = self.bcx;
|
||||
let mut static_ti = none;
|
||||
let lltydesc = get_tydesc(bcx.ccx(), t, static_ti);
|
||||
lazily_emit_all_tydesc_glue(bcx.ccx(), copy static_ti);
|
||||
PointerCast(bcx, lltydesc, T_ptr(self.tydesc_ty))
|
||||
}
|
||||
|
||||
fn c_mt(mt: ty::mt) -> ~[ValueRef] {
|
||||
~[self.c_uint(mt.mutbl as uint),
|
||||
self.c_tydesc(mt.ty)]
|
||||
}
|
||||
|
||||
fn visit(ty_name: str, args: ~[ValueRef]) {
|
||||
let tcx = self.bcx.tcx();
|
||||
let mth_idx = option::get(ty::method_idx(@("visit_" + ty_name),
|
||||
@ -58,29 +73,22 @@ impl methods for reflector {
|
||||
for args.eachi |i, a| {
|
||||
#debug("arg %u: %s", i, val_str(bcx.ccx().tn, a));
|
||||
}
|
||||
self.bcx =
|
||||
let d = empty_dest_cell();
|
||||
let bcx =
|
||||
trans_call_inner(self.bcx, none, mth_ty, ty::mk_bool(tcx),
|
||||
get_lval, arg_vals(args), ignore);
|
||||
get_lval, arg_vals(args), by_val(d));
|
||||
let next_bcx = sub_block(bcx, "next");
|
||||
CondBr(bcx, *d, next_bcx.llbb, self.final_bcx.llbb);
|
||||
self.bcx = next_bcx
|
||||
}
|
||||
|
||||
fn visit_tydesc(t: ty::t) {
|
||||
self.bcx =
|
||||
call_tydesc_glue(self.bcx, self.visitor_val, t,
|
||||
abi::tydesc_field_visit_glue);
|
||||
}
|
||||
|
||||
fn bracketed_t(bracket_name: str, t: ty::t, extra: ~[ValueRef]) {
|
||||
fn bracketed(bracket_name: str, extra: ~[ValueRef],
|
||||
inner: fn()) {
|
||||
self.visit("enter_" + bracket_name, extra);
|
||||
self.visit_tydesc(t);
|
||||
inner();
|
||||
self.visit("leave_" + bracket_name, extra);
|
||||
}
|
||||
|
||||
fn bracketed_mt(bracket_name: str, mt: ty::mt, extra: ~[ValueRef]) {
|
||||
self.bracketed_t(bracket_name, mt.ty,
|
||||
vec::append(~[self.c_uint(mt.mutbl as uint)],
|
||||
extra));
|
||||
}
|
||||
|
||||
fn vstore_name_and_extra(t: ty::t,
|
||||
vstore: ty::vstore,
|
||||
f: fn(str,~[ValueRef])) {
|
||||
@ -127,7 +135,8 @@ impl methods for reflector {
|
||||
ty::ty_float(ast::ty_f64) { self.leaf("f64") }
|
||||
ty::ty_str { self.leaf("str") }
|
||||
|
||||
ty::ty_vec(mt) { self.bracketed_mt("vec", mt, ~[]) }
|
||||
ty::ty_vec(mt) { self.visit("vec", self.c_mt(mt)) }
|
||||
ty::ty_unboxed_vec(mt) { self.visit("vec", self.c_mt(mt)) }
|
||||
ty::ty_estr(vst) {
|
||||
do self.vstore_name_and_extra(t, vst) |name, extra| {
|
||||
self.visit("estr_" + name, extra)
|
||||
@ -135,34 +144,38 @@ impl methods for reflector {
|
||||
}
|
||||
ty::ty_evec(mt, vst) {
|
||||
do self.vstore_name_and_extra(t, vst) |name, extra| {
|
||||
self.bracketed_mt("evec_" + name, mt, extra)
|
||||
self.visit("evec_" + name, extra +
|
||||
self.c_mt(mt))
|
||||
}
|
||||
}
|
||||
ty::ty_box(mt) { self.bracketed_mt("box", mt, ~[]) }
|
||||
ty::ty_uniq(mt) { self.bracketed_mt("uniq", mt, ~[]) }
|
||||
ty::ty_ptr(mt) { self.bracketed_mt("ptr", mt, ~[]) }
|
||||
ty::ty_rptr(_, mt) { self.bracketed_mt("rptr", mt, ~[]) }
|
||||
ty::ty_box(mt) { self.visit("box", self.c_mt(mt)) }
|
||||
ty::ty_uniq(mt) { self.visit("uniq", self.c_mt(mt)) }
|
||||
ty::ty_ptr(mt) { self.visit("ptr", self.c_mt(mt)) }
|
||||
ty::ty_rptr(_, mt) { self.visit("rptr", self.c_mt(mt)) }
|
||||
|
||||
ty::ty_rec(fields) {
|
||||
let extra = (vec::append(~[self.c_uint(vec::len(fields))],
|
||||
self.c_size_and_align(t)));
|
||||
self.visit("enter_rec", extra);
|
||||
for fields.eachi |i, field| {
|
||||
self.bracketed_mt("rec_field", field.mt,
|
||||
~[self.c_uint(i),
|
||||
self.c_slice(*field.ident)]);
|
||||
do self.bracketed("rec",
|
||||
~[self.c_uint(vec::len(fields))]
|
||||
+ self.c_size_and_align(t)) {
|
||||
for fields.eachi |i, field| {
|
||||
self.visit("rec_field",
|
||||
~[self.c_uint(i),
|
||||
self.c_slice(*field.ident)]
|
||||
+ self.c_mt(field.mt));
|
||||
}
|
||||
}
|
||||
self.visit("leave_rec", extra);
|
||||
}
|
||||
|
||||
ty::ty_tup(tys) {
|
||||
let extra = (vec::append(~[self.c_uint(vec::len(tys))],
|
||||
self.c_size_and_align(t)));
|
||||
self.visit("enter_tup", extra);
|
||||
for tys.eachi |i, t| {
|
||||
self.bracketed_t("tup_field", t, ~[self.c_uint(i)]);
|
||||
do self.bracketed("tup",
|
||||
~[self.c_uint(vec::len(tys))]
|
||||
+ self.c_size_and_align(t)) {
|
||||
for tys.eachi |i, t| {
|
||||
self.visit("tup_field",
|
||||
~[self.c_uint(i),
|
||||
self.c_tydesc(t)]);
|
||||
}
|
||||
}
|
||||
self.visit("leave_tup", extra);
|
||||
}
|
||||
|
||||
// FIXME (#2594): fetch constants out of intrinsic:: for the
|
||||
@ -203,12 +216,14 @@ impl methods for reflector {
|
||||
}
|
||||
}
|
||||
};
|
||||
self.bracketed_t("fn_input", arg.ty,
|
||||
~[self.c_uint(i),
|
||||
self.c_uint(modeval)]);
|
||||
self.visit("fn_input",
|
||||
~[self.c_uint(i),
|
||||
self.c_uint(modeval),
|
||||
self.c_tydesc(arg.ty)]);
|
||||
}
|
||||
self.bracketed_t("fn_output", fty.output,
|
||||
~[self.c_uint(retval)]);
|
||||
self.visit("fn_output",
|
||||
~[self.c_uint(retval),
|
||||
self.c_tydesc(fty.output)]);
|
||||
self.visit("leave_fn", extra);
|
||||
}
|
||||
|
||||
@ -216,16 +231,16 @@ impl methods for reflector {
|
||||
let bcx = self.bcx;
|
||||
let tcx = bcx.ccx().tcx;
|
||||
let fields = ty::class_items_as_fields(tcx, did, substs);
|
||||
let extra = vec::append(~[self.c_uint(vec::len(fields))],
|
||||
self.c_size_and_align(t));
|
||||
|
||||
self.visit("enter_class", extra);
|
||||
for fields.eachi |i, field| {
|
||||
self.bracketed_mt("class_field", field.mt,
|
||||
~[self.c_uint(i),
|
||||
self.c_slice(*field.ident)]);
|
||||
do self.bracketed("class", ~[self.c_uint(vec::len(fields))]
|
||||
+ self.c_size_and_align(t)) {
|
||||
for fields.eachi |i, field| {
|
||||
self.visit("class_field",
|
||||
~[self.c_uint(i),
|
||||
self.c_slice(*field.ident)]
|
||||
+ self.c_mt(field.mt));
|
||||
}
|
||||
}
|
||||
self.visit("leave_class", extra);
|
||||
}
|
||||
|
||||
// FIXME (#2595): visiting all the variants in turn is probably
|
||||
@ -236,23 +251,24 @@ impl methods for reflector {
|
||||
let bcx = self.bcx;
|
||||
let tcx = bcx.ccx().tcx;
|
||||
let variants = ty::substd_enum_variants(tcx, did, substs);
|
||||
let extra = vec::append(~[self.c_uint(vec::len(variants))],
|
||||
self.c_size_and_align(t));
|
||||
|
||||
self.visit("enter_enum", extra);
|
||||
for variants.eachi |i, v| {
|
||||
let extra = ~[self.c_uint(i),
|
||||
self.c_int(v.disr_val),
|
||||
self.c_uint(vec::len(v.args)),
|
||||
self.c_slice(*v.name)];
|
||||
self.visit("enter_enum_variant", extra);
|
||||
for v.args.eachi |j, a| {
|
||||
self.bracketed_t("enum_variant_field", a,
|
||||
~[self.c_uint(j)]);
|
||||
do self.bracketed("enum",
|
||||
~[self.c_uint(vec::len(variants))]
|
||||
+ self.c_size_and_align(t)) {
|
||||
for variants.eachi |i, v| {
|
||||
do self.bracketed("enum_variant",
|
||||
~[self.c_uint(i),
|
||||
self.c_int(v.disr_val),
|
||||
self.c_uint(vec::len(v.args)),
|
||||
self.c_slice(*v.name)]) {
|
||||
for v.args.eachi |j, a| {
|
||||
self.visit("enum_variant_field",
|
||||
~[self.c_uint(j),
|
||||
self.c_tydesc(a)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.visit("leave_enum_variant", extra);
|
||||
}
|
||||
self.visit("leave_enum", extra);
|
||||
}
|
||||
|
||||
// Miscallaneous extra types
|
||||
@ -263,7 +279,7 @@ impl methods for reflector {
|
||||
ty::ty_self { self.leaf("self") }
|
||||
ty::ty_type { self.leaf("type") }
|
||||
ty::ty_opaque_box { self.leaf("opaque_box") }
|
||||
ty::ty_constr(t, _) { self.bracketed_t("constr", t, ~[]) }
|
||||
ty::ty_constr(t, _) { self.visit("constr", ~[self.c_tydesc(t)]) }
|
||||
ty::ty_opaque_closure_ptr(ck) {
|
||||
let ckval = alt ck {
|
||||
ty::ck_block { 0u }
|
||||
@ -272,7 +288,6 @@ impl methods for reflector {
|
||||
};
|
||||
self.visit("closure_ptr", ~[self.c_uint(ckval)])
|
||||
}
|
||||
ty::ty_unboxed_vec(mt) { self.bracketed_mt("vec", mt, ~[]) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,12 +297,18 @@ fn emit_calls_to_trait_visit_ty(bcx: block, t: ty::t,
|
||||
visitor_val: ValueRef,
|
||||
visitor_iid: def_id) -> block {
|
||||
|
||||
let final = sub_block(bcx, "final");
|
||||
assert bcx.ccx().tcx.intrinsic_defs.contains_key(@"tydesc");
|
||||
let (_, tydesc_ty) = bcx.ccx().tcx.intrinsic_defs.get(@"tydesc");
|
||||
let tydesc_ty = type_of::type_of(bcx.ccx(), tydesc_ty);
|
||||
let r = reflector({
|
||||
visitor_val: visitor_val,
|
||||
visitor_methods: ty::trait_methods(bcx.tcx(), visitor_iid),
|
||||
final_bcx: final,
|
||||
tydesc_ty: tydesc_ty,
|
||||
mut bcx: bcx
|
||||
});
|
||||
|
||||
r.visit_ty(t);
|
||||
ret r.bcx;
|
||||
Br(r.bcx, final.llbb);
|
||||
ret final;
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
|
||||
abi, _) {
|
||||
if abi == foreign_abi_rust_intrinsic {
|
||||
let flags = alt check *i.ident {
|
||||
"visit_ty" { use_repr | use_tydesc }
|
||||
"size_of" | "pref_align_of" | "min_align_of" |
|
||||
"init" | "reinterpret_cast" | "move_val" | "move_val_init" {
|
||||
use_repr
|
||||
@ -87,7 +86,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
|
||||
"atomic_xchng_rel" | "atomic_add_rel" | "atomic_sub_rel" {
|
||||
0u
|
||||
}
|
||||
"forget" | "addr_of" { 0u }
|
||||
"visit_tydesc" | "forget" | "addr_of" { 0u }
|
||||
};
|
||||
for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;}
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ type ctxt =
|
||||
node_type_substs: hashmap<node_id, ~[t]>,
|
||||
|
||||
items: ast_map::map,
|
||||
intrinsic_traits: hashmap<ast::ident, (ast::def_id, t)>,
|
||||
intrinsic_defs: hashmap<ast::ident, (ast::def_id, t)>,
|
||||
freevars: freevars::freevar_map,
|
||||
tcache: type_cache,
|
||||
rcache: creader_cache,
|
||||
@ -526,7 +526,7 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
|
||||
node_types: @smallintmap::mk(),
|
||||
node_type_substs: map::int_hash(),
|
||||
items: amap,
|
||||
intrinsic_traits: map::box_str_hash(),
|
||||
intrinsic_defs: map::box_str_hash(),
|
||||
freevars: freevars,
|
||||
tcache: ast_util::new_def_hash(),
|
||||
rcache: mk_rcache(),
|
||||
|
@ -2254,7 +2254,6 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
||||
let (n_tps, inputs, output) = alt *it.ident {
|
||||
"size_of" |
|
||||
"pref_align_of" | "min_align_of" { (1u, ~[], ty::mk_uint(ccx.tcx)) }
|
||||
"get_tydesc" { (1u, ~[], ty::mk_nil_ptr(tcx)) }
|
||||
"init" { (1u, ~[], param(ccx, 0u)) }
|
||||
"forget" { (1u, ~[arg(ast::by_move, param(ccx, 0u))],
|
||||
ty::mk_nil(tcx)) }
|
||||
@ -2277,10 +2276,19 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
||||
ty::mk_int(tcx))
|
||||
}
|
||||
|
||||
"visit_ty" {
|
||||
assert ccx.tcx.intrinsic_traits.contains_key(@"ty_visitor");
|
||||
let (_, visitor_trait) = ccx.tcx.intrinsic_traits.get(@"ty_visitor");
|
||||
(1u, ~[arg(ast::by_ref, visitor_trait)], ty::mk_nil(tcx))
|
||||
"get_tydesc" {
|
||||
// FIXME (#2712): return *intrinsic::tydesc, not *()
|
||||
(1u, ~[], ty::mk_nil_ptr(tcx))
|
||||
}
|
||||
"visit_tydesc" {
|
||||
assert ccx.tcx.intrinsic_defs.contains_key(@"tydesc");
|
||||
assert ccx.tcx.intrinsic_defs.contains_key(@"ty_visitor");
|
||||
let (_, tydesc_ty) = ccx.tcx.intrinsic_defs.get(@"tydesc");
|
||||
let (_, visitor_trait) = ccx.tcx.intrinsic_defs.get(@"ty_visitor");
|
||||
let td_ptr = ty::mk_ptr(ccx.tcx, {ty: tydesc_ty,
|
||||
mutbl: ast::m_imm});
|
||||
(0u, ~[arg(ast::by_val, td_ptr),
|
||||
arg(ast::by_ref, visitor_trait)], ty::mk_nil(tcx))
|
||||
}
|
||||
"frame_address" {
|
||||
let fty = ty::mk_fn(ccx.tcx, {
|
||||
|
@ -33,16 +33,25 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
|
||||
alt crate_item.node {
|
||||
ast::item_mod(m) {
|
||||
for m.items.each |intrinsic_item| {
|
||||
let def_id = { crate: ast::local_crate,
|
||||
node: intrinsic_item.id };
|
||||
let substs = {self_r: none, self_ty: none, tps: ~[]};
|
||||
|
||||
alt intrinsic_item.node {
|
||||
|
||||
ast::item_trait(_, _, _) {
|
||||
let def_id = { crate: ast::local_crate,
|
||||
node: intrinsic_item.id };
|
||||
let substs = {self_r: none, self_ty: none, tps: ~[]};
|
||||
let ty = ty::mk_trait(ccx.tcx, def_id, substs);
|
||||
ccx.tcx.intrinsic_traits.insert
|
||||
ccx.tcx.intrinsic_defs.insert
|
||||
(intrinsic_item.ident, (def_id, ty));
|
||||
}
|
||||
_ { }
|
||||
|
||||
ast::item_enum(_, _, _) {
|
||||
let ty = ty::mk_enum(ccx.tcx, def_id, substs);
|
||||
ccx.tcx.intrinsic_defs.insert
|
||||
(intrinsic_item.ident, (def_id, ty));
|
||||
}
|
||||
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,17 @@
|
||||
// FIXME: un-xfail after snapshot
|
||||
// xfail-test
|
||||
|
||||
import intrinsic::ty_visitor;
|
||||
import intrinsic::{tydesc, get_tydesc, visit_tydesc, ty_visitor};
|
||||
import libc::c_void;
|
||||
|
||||
/// High-level interfaces to `intrinsic::visit_ty` reflection system.
|
||||
// FIXME: this is a near-duplicate of code in core::vec.
|
||||
type unboxed_vec_repr = {
|
||||
mut fill: uint,
|
||||
mut alloc: uint,
|
||||
data: u8
|
||||
};
|
||||
|
||||
#[doc = "High-level interfaces to `intrinsic::visit_ty` reflection system."]
|
||||
|
||||
/// Iface for visitor that wishes to reflect on data.
|
||||
iface movable_ptr {
|
||||
@ -201,114 +208,77 @@ impl ptr_visitor<V: ty_visitor movable_ptr>
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_box(mtbl: uint) -> bool {
|
||||
fn visit_box(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<@u8>();
|
||||
if ! self.inner.visit_enter_box(mtbl) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_box(mtbl: uint) -> bool {
|
||||
if ! self.inner.visit_leave_box(mtbl) { ret false; }
|
||||
if ! self.inner.visit_box(mtbl, inner) { ret false; }
|
||||
self.bump_past::<@u8>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_uniq(mtbl: uint) -> bool {
|
||||
fn visit_uniq(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<~u8>();
|
||||
if ! self.inner.visit_enter_uniq(mtbl) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_uniq(mtbl: uint) -> bool {
|
||||
if ! self.inner.visit_leave_uniq(mtbl) { ret false; }
|
||||
if ! self.inner.visit_uniq(mtbl, inner) { ret false; }
|
||||
self.bump_past::<~u8>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_ptr(mtbl: uint) -> bool {
|
||||
fn visit_ptr(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<*u8>();
|
||||
if ! self.inner.visit_enter_ptr(mtbl) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_ptr(mtbl: uint) -> bool {
|
||||
if ! self.inner.visit_leave_ptr(mtbl) { ret false; }
|
||||
if ! self.inner.visit_ptr(mtbl, inner) { ret false; }
|
||||
self.bump_past::<*u8>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_rptr(mtbl: uint) -> bool {
|
||||
fn visit_rptr(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<&static.u8>();
|
||||
if ! self.inner.visit_enter_rptr(mtbl) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_rptr(mtbl: uint) -> bool {
|
||||
if ! self.inner.visit_leave_rptr(mtbl) { ret false; }
|
||||
if ! self.inner.visit_rptr(mtbl, inner) { ret false; }
|
||||
self.bump_past::<&static.u8>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_vec(mtbl: uint) -> bool {
|
||||
self.align_to::<~[u8]>();
|
||||
if ! self.inner.visit_enter_vec(mtbl) { ret false; }
|
||||
fn visit_unboxed_vec(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<unboxed_vec_repr>();
|
||||
// FIXME: Inner really has to move its own pointers on this one.
|
||||
// or else possibly we could have some weird interface wherein we
|
||||
// read-off a word from inner's pointers, but the read-word has to
|
||||
// always be the same in all sub-pointers? Dubious.
|
||||
if ! self.inner.visit_vec(mtbl, inner) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_vec(mtbl: uint) -> bool {
|
||||
if ! self.inner.visit_leave_vec(mtbl) { ret false; }
|
||||
self.bump_past::<~[u8]>();
|
||||
fn visit_vec(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<[u8]>();
|
||||
if ! self.inner.visit_vec(mtbl, inner) { ret false; }
|
||||
self.bump_past::<[u8]>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_evec_box(mtbl: uint) -> bool {
|
||||
self.align_to::<@[u8]>();
|
||||
if ! self.inner.visit_enter_evec_box(mtbl) { ret false; }
|
||||
fn visit_evec_box(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<[u8]/@>();
|
||||
if ! self.inner.visit_evec_box(mtbl, inner) { ret false; }
|
||||
self.bump_past::<[u8]/@>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_evec_box(mtbl: uint) -> bool {
|
||||
if ! self.inner.visit_leave_evec_box(mtbl) { ret false; }
|
||||
self.bump_past::<@[u8]>();
|
||||
fn visit_evec_uniq(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<[u8]/~>();
|
||||
if ! self.inner.visit_evec_uniq(mtbl, inner) { ret false; }
|
||||
self.bump_past::<[u8]/~>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_evec_uniq(mtbl: uint) -> bool {
|
||||
self.align_to::<~[u8]>();
|
||||
if ! self.inner.visit_enter_evec_uniq(mtbl) { ret false; }
|
||||
fn visit_evec_slice(mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.align_to::<[u8]/&static>();
|
||||
if ! self.inner.visit_evec_slice(mtbl, inner) { ret false; }
|
||||
self.bump_past::<[u8]/&static>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_evec_uniq(mtbl: uint) -> bool {
|
||||
if ! self.inner.visit_leave_evec_uniq(mtbl) { ret false; }
|
||||
self.bump_past::<~[u8]>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_evec_slice(mtbl: uint) -> bool {
|
||||
self.align_to::<&[u8]static>();
|
||||
if ! self.inner.visit_enter_evec_slice(mtbl) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_evec_slice(mtbl: uint) -> bool {
|
||||
if ! self.inner.visit_leave_evec_slice(mtbl) { ret false; }
|
||||
self.bump_past::<&[u8]static>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_evec_fixed(mtbl: uint, n: uint,
|
||||
sz: uint, align: uint) -> bool {
|
||||
fn visit_evec_fixed(mtbl: uint, n: uint,
|
||||
sz: uint, align: uint,
|
||||
inner: *tydesc) -> bool {
|
||||
self.align(align);
|
||||
if ! self.inner.visit_enter_evec_fixed(mtbl, n, sz, align) {
|
||||
ret false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_evec_fixed(mtbl: uint, n: uint,
|
||||
sz: uint, align: uint) -> bool {
|
||||
if ! self.inner.visit_leave_evec_fixed(mtbl, n, sz, align) {
|
||||
if ! self.inner.visit_evec_fixed(mtbl, n, sz, align, inner) {
|
||||
ret false;
|
||||
}
|
||||
self.bump(sz);
|
||||
@ -321,21 +291,14 @@ impl ptr_visitor<V: ty_visitor movable_ptr>
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_rec_field(mtbl: uint, i: uint,
|
||||
name: str/&) -> bool {
|
||||
if ! self.inner.visit_enter_rec_field(mtbl, i, name) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_rec_field(mtbl: uint, i: uint,
|
||||
name: str/&) -> bool {
|
||||
if ! self.inner.visit_leave_rec_field(mtbl, i, name) { ret false; }
|
||||
fn visit_rec_field(i: uint, name: str/&,
|
||||
mtbl: uint, inner: *tydesc) -> bool {
|
||||
if ! self.inner.visit_rec_field(i, name, mtbl, inner) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_rec(n_fields: uint, sz: uint, align: uint) -> bool {
|
||||
if ! self.inner.visit_leave_rec(n_fields, sz, align) { ret false; }
|
||||
self.bump(sz);
|
||||
true
|
||||
}
|
||||
|
||||
@ -347,17 +310,9 @@ impl ptr_visitor<V: ty_visitor movable_ptr>
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_class_field(mtbl: uint, i: uint,
|
||||
name: str/&) -> bool {
|
||||
if ! self.inner.visit_enter_class_field(mtbl, i, name) {
|
||||
ret false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_class_field(mtbl: uint, i: uint,
|
||||
name: str/&) -> bool {
|
||||
if ! self.inner.visit_leave_class_field(mtbl, i, name) {
|
||||
fn visit_class_field(i: uint, name: str/&,
|
||||
mtbl: uint, inner: *tydesc) -> bool {
|
||||
if ! self.inner.visit_class_field(i, name, mtbl, inner) {
|
||||
ret false;
|
||||
}
|
||||
true
|
||||
@ -367,7 +322,6 @@ impl ptr_visitor<V: ty_visitor movable_ptr>
|
||||
if ! self.inner.visit_leave_class(n_fields, sz, align) {
|
||||
ret false;
|
||||
}
|
||||
self.bump(sz);
|
||||
true
|
||||
}
|
||||
|
||||
@ -377,47 +331,31 @@ impl ptr_visitor<V: ty_visitor movable_ptr>
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_tup_field(i: uint) -> bool {
|
||||
if ! self.inner.visit_enter_tup_field(i) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_tup_field(i: uint) -> bool {
|
||||
if ! self.inner.visit_leave_tup_field(i) { ret false; }
|
||||
fn visit_tup_field(i: uint, inner: *tydesc) -> bool {
|
||||
if ! self.inner.visit_tup_field(i, inner) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_tup(n_fields: uint, sz: uint, align: uint) -> bool {
|
||||
if ! self.inner.visit_leave_tup(n_fields, sz, align) { ret false; }
|
||||
self.bump(sz);
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_fn(purity: uint, proto: uint,
|
||||
n_inputs: uint, retstyle: uint) -> bool {
|
||||
if ! self.inner.visit_enter_fn(purity, proto, n_inputs, retstyle) {
|
||||
ret false;
|
||||
ret false
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_fn_input(i: uint, mode: uint) -> bool {
|
||||
if ! self.inner.visit_enter_fn_input(i, mode) { ret false; }
|
||||
fn visit_fn_input(i: uint, mode: uint, inner: *tydesc) -> bool {
|
||||
if ! self.inner.visit_fn_input(i, mode, inner) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_fn_input(i: uint, mode: uint) -> bool {
|
||||
if ! self.inner.visit_leave_fn_input(i, mode) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_fn_output(retstyle: uint) -> bool {
|
||||
if ! self.inner.visit_enter_fn_output(retstyle) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_fn_output(retstyle: uint) -> bool {
|
||||
if ! self.inner.visit_leave_fn_output(retstyle) { ret false; }
|
||||
fn visit_fn_output(retstyle: uint, inner: *tydesc) -> bool {
|
||||
if ! self.inner.visit_fn_output(retstyle, inner) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
@ -446,13 +384,8 @@ impl ptr_visitor<V: ty_visitor movable_ptr>
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_enum_variant_field(i: uint) -> bool {
|
||||
if ! self.inner.visit_enter_enum_variant_field(i) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_enum_variant_field(i: uint) -> bool {
|
||||
if ! self.inner.visit_leave_enum_variant_field(i) { ret false; }
|
||||
fn visit_enum_variant_field(i: uint, inner: *tydesc) -> bool {
|
||||
if ! self.inner.visit_enum_variant_field(i, inner) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
@ -469,29 +402,16 @@ impl ptr_visitor<V: ty_visitor movable_ptr>
|
||||
|
||||
fn visit_leave_enum(n_variants: uint, sz: uint, align: uint) -> bool {
|
||||
if ! self.inner.visit_leave_enum(n_variants, sz, align) { ret false; }
|
||||
self.bump(sz);
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_iface() -> bool {
|
||||
fn visit_trait() -> bool {
|
||||
self.align_to::<ty_visitor>();
|
||||
if ! self.inner.visit_iface() { ret false; }
|
||||
self.bump_past::<ty_visitor>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_res() -> bool {
|
||||
// FIXME: I _think_ a resource takes no space,
|
||||
// but I might be wrong.
|
||||
if ! self.inner.visit_enter_res() { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_res() -> bool {
|
||||
if ! self.inner.visit_leave_res() { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_var() -> bool {
|
||||
if ! self.inner.visit_var() { ret false; }
|
||||
true
|
||||
@ -526,13 +446,8 @@ impl ptr_visitor<V: ty_visitor movable_ptr>
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_enter_constr() -> bool {
|
||||
if ! self.inner.visit_enter_constr() { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_leave_constr() -> bool {
|
||||
if ! self.inner.visit_leave_constr() { ret false; }
|
||||
fn visit_constr(inner: *tydesc) -> bool {
|
||||
if ! self.inner.visit_constr(inner) { ret false; }
|
||||
true
|
||||
}
|
||||
|
||||
@ -556,6 +471,13 @@ impl extra_methods for my_visitor {
|
||||
f(*(self.ptr1 as *T));
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_inner(inner: *tydesc) -> bool {
|
||||
let u = my_visitor(*self);
|
||||
let v = ptr_visit_adaptor({inner: u});
|
||||
visit_tydesc(inner, v as ty_visitor);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl of movable_ptr for my_visitor {
|
||||
@ -570,19 +492,15 @@ impl of ty_visitor for my_visitor {
|
||||
fn visit_bot() -> bool { true }
|
||||
fn visit_nil() -> bool { true }
|
||||
fn visit_bool() -> bool {
|
||||
/*
|
||||
self.get::<bool>() {|b|
|
||||
self.vals += ~[bool::to_str(b)];
|
||||
}
|
||||
*/
|
||||
true
|
||||
}
|
||||
fn visit_int() -> bool {
|
||||
/*
|
||||
self.get::<int>() {|i|
|
||||
self.vals += ~[int::to_str(i, 10u)];
|
||||
}
|
||||
*/
|
||||
true
|
||||
}
|
||||
fn visit_i8() -> bool { true }
|
||||
@ -608,70 +526,60 @@ impl of ty_visitor for my_visitor {
|
||||
fn visit_estr_slice() -> bool { true }
|
||||
fn visit_estr_fixed(_sz: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_box(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_box(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_uniq(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_uniq(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_ptr(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_ptr(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_rptr(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_rptr(_mtbl: uint) -> bool { true }
|
||||
fn visit_box(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_uniq(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_ptr(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_rptr(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
|
||||
fn visit_enter_vec(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_vec(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_evec_box(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_evec_box(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_evec_uniq(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_evec_uniq(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_evec_slice(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_evec_slice(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_evec_fixed(_mtbl: uint, _n: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_leave_evec_fixed(_mtbl: uint, _n: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_vec(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_unboxed_vec(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_evec_box(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_evec_uniq(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_evec_slice(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_evec_fixed(_n: uint, _mtbl: uint,
|
||||
_sz: uint, _align: uint,
|
||||
_inner: *tydesc) -> bool { true }
|
||||
|
||||
fn visit_enter_rec(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_enter_rec_field(_mtbl: uint, _i: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_leave_rec_field(_mtbl: uint, _i: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_rec_field(_i: uint, _name: str/&,
|
||||
_mtbl: uint, inner: *tydesc) -> bool {
|
||||
#error("rec field!");
|
||||
self.visit_inner(inner)
|
||||
}
|
||||
fn visit_leave_rec(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_class(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_enter_class_field(_mtbl: uint, _i: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_leave_class_field(_mtbl: uint, _i: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_class_field(_i: uint, _name: str/&,
|
||||
_mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.visit_inner(inner)
|
||||
}
|
||||
fn visit_leave_class(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_tup(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_enter_tup_field(_i: uint) -> bool { true }
|
||||
fn visit_leave_tup_field(_i: uint) -> bool { true }
|
||||
fn visit_tup_field(_i: uint, inner: *tydesc) -> bool {
|
||||
#error("tup field!");
|
||||
self.visit_inner(inner)
|
||||
}
|
||||
fn visit_leave_tup(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_fn(_purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||
fn visit_enter_fn_input(_i: uint, _mode: uint) -> bool { true }
|
||||
fn visit_leave_fn_input(_i: uint, _mode: uint) -> bool { true }
|
||||
fn visit_enter_fn_output(_retstyle: uint) -> bool { true }
|
||||
fn visit_leave_fn_output(_retstyle: uint) -> bool { true }
|
||||
fn visit_leave_fn(_purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_enum(_n_variants: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
_sz: uint, _align: uint) -> bool {
|
||||
// FIXME: this needs to rewind between enum variants, or something.
|
||||
true
|
||||
}
|
||||
fn visit_enter_enum_variant(_variant: uint,
|
||||
_disr_val: int,
|
||||
_n_fields: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_enter_enum_variant_field(_i: uint) -> bool { true }
|
||||
fn visit_leave_enum_variant_field(_i: uint) -> bool { true }
|
||||
fn visit_enum_variant_field(_i: uint, inner: *tydesc) -> bool {
|
||||
self.visit_inner(inner)
|
||||
}
|
||||
fn visit_leave_enum_variant(_variant: uint,
|
||||
_disr_val: int,
|
||||
_n_fields: uint,
|
||||
@ -679,33 +587,45 @@ impl of ty_visitor for my_visitor {
|
||||
fn visit_leave_enum(_n_variants: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
|
||||
fn visit_iface() -> bool { true }
|
||||
fn visit_enter_res() -> bool { true }
|
||||
fn visit_leave_res() -> bool { true }
|
||||
fn visit_enter_fn(_purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||
fn visit_fn_input(_i: uint, _mode: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_fn_output(_retstyle: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_leave_fn(_purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||
|
||||
|
||||
fn visit_trait() -> bool { true }
|
||||
fn visit_var() -> bool { true }
|
||||
fn visit_var_integral() -> bool { true }
|
||||
fn visit_param(_i: uint) -> bool { true }
|
||||
fn visit_self() -> bool { true }
|
||||
fn visit_type() -> bool { true }
|
||||
fn visit_opaque_box() -> bool { true }
|
||||
fn visit_enter_constr() -> bool { true }
|
||||
fn visit_leave_constr() -> bool { true }
|
||||
fn visit_constr(_inner: *tydesc) -> bool { true }
|
||||
fn visit_closure_ptr(_ck: uint) -> bool { true }
|
||||
}
|
||||
|
||||
fn get_tydesc_for<T>(&&_t: T) -> *tydesc {
|
||||
get_tydesc::<T>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let r = (1,2,3,true,false);
|
||||
let r = (1,2,3,true,false,{x:5,y:4,z:3});
|
||||
let p = ptr::addr_of(r) as *c_void;
|
||||
let u = my_visitor(@{mut ptr1: p,
|
||||
mut ptr2: p,
|
||||
mut vals: ~[]});
|
||||
let v = ptr_visit_adaptor({inner: u});
|
||||
let vv = v as intrinsic::ty_visitor;
|
||||
intrinsic::visit_ty::<(int,int,int,bool,bool)>(vv);
|
||||
let td = get_tydesc_for(r);
|
||||
unsafe { #error("tydesc sz: %u, align: %u",
|
||||
(*td).size, (*td).align); }
|
||||
let v = v as ty_visitor;
|
||||
visit_tydesc(td, v);
|
||||
|
||||
for (copy u.vals).each {|s|
|
||||
io::println(#fmt("val: %s", s));
|
||||
}
|
||||
assert u.vals == ["1", "2", "3", "true", "false"];
|
||||
#error("%?", copy u.vals);
|
||||
assert u.vals == ["1", "2", "3", "true", "false", "5", "4", "3"];
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
// FIXME: un-xfail after snapshot
|
||||
// xfail-test
|
||||
|
||||
import intrinsic::{tydesc, get_tydesc, visit_tydesc, ty_visitor};
|
||||
enum my_visitor = @{ mut types: ~[str] };
|
||||
|
||||
impl of intrinsic::ty_visitor for my_visitor {
|
||||
impl of ty_visitor for my_visitor {
|
||||
fn visit_bot() -> bool {
|
||||
self.types += ["bot"];
|
||||
#error("visited bot type");
|
||||
@ -55,98 +56,91 @@ impl of intrinsic::ty_visitor for my_visitor {
|
||||
fn visit_estr_slice() -> bool { true }
|
||||
fn visit_estr_fixed(_sz: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_box(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_box(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_uniq(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_uniq(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_ptr(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_ptr(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_rptr(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_rptr(_mtbl: uint) -> bool { true }
|
||||
fn visit_box(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_uniq(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_ptr(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_rptr(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
|
||||
fn visit_enter_vec(_mtbl: uint) -> bool {
|
||||
fn visit_vec(_mtbl: uint, inner: *tydesc) -> bool {
|
||||
self.types += ["["];
|
||||
#error("visited enter-vec");
|
||||
true
|
||||
}
|
||||
fn visit_leave_vec(_mtbl: uint) -> bool {
|
||||
visit_tydesc(inner, my_visitor(*self) as ty_visitor);
|
||||
self.types += ["]"];
|
||||
#error("visited leave-vec");
|
||||
true
|
||||
}
|
||||
fn visit_enter_evec_box(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_evec_box(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_evec_uniq(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_evec_uniq(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_evec_slice(_mtbl: uint) -> bool { true }
|
||||
fn visit_leave_evec_slice(_mtbl: uint) -> bool { true }
|
||||
fn visit_enter_evec_fixed(_mtbl: uint, _sz: uint) -> bool { true }
|
||||
fn visit_leave_evec_fixed(_mtbl: uint, _sz: uint) -> bool { true }
|
||||
fn visit_unboxed_vec(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_evec_box(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_evec_uniq(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_evec_slice(_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_evec_fixed(_n: uint, _mtbl: uint,
|
||||
_sz: uint, _align: uint,
|
||||
_inner: *tydesc) -> bool { true }
|
||||
|
||||
fn visit_enter_rec(_n_fields: uint) -> bool { true }
|
||||
fn visit_enter_rec_field(_mtbl: uint, _i: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_leave_rec_field(_mtbl: uint, _i: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_leave_rec(_n_fields: uint) -> bool { true }
|
||||
fn visit_enter_rec(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_rec_field(_i: uint, _name: str/&,
|
||||
_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_leave_rec(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_class(_n_fields: uint) -> bool { true }
|
||||
fn visit_enter_class_field(_mtbl: uint, _i: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_leave_class_field(_mtbl: uint, _i: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_leave_class(_n_fields: uint) -> bool { true }
|
||||
fn visit_enter_class(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_class_field(_i: uint, _name: str/&,
|
||||
_mtbl: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_leave_class(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_tup(_n_fields: uint) -> bool { true }
|
||||
fn visit_enter_tup_field(_i: uint) -> bool { true }
|
||||
fn visit_leave_tup_field(_i: uint) -> bool { true }
|
||||
fn visit_leave_tup(_n_fields: uint) -> bool { true }
|
||||
fn visit_enter_tup(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_tup_field(_i: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_leave_tup(_n_fields: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_fn(_purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||
fn visit_enter_fn_input(_i: uint, _mode: uint) -> bool { true }
|
||||
fn visit_leave_fn_input(_i: uint, _mode: uint) -> bool { true }
|
||||
fn visit_enter_fn_output(_retstyle: uint) -> bool { true }
|
||||
fn visit_leave_fn_output(_retstyle: uint) -> bool { true }
|
||||
fn visit_leave_fn(_purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||
|
||||
fn visit_enter_enum(_n_variants: uint) -> bool { true }
|
||||
fn visit_enter_enum(_n_variants: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
fn visit_enter_enum_variant(_variant: uint,
|
||||
_disr_val: int,
|
||||
_n_fields: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_enter_enum_variant_field(_i: uint) -> bool { true }
|
||||
fn visit_leave_enum_variant_field(_i: uint) -> bool { true }
|
||||
fn visit_enum_variant_field(_i: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_leave_enum_variant(_variant: uint,
|
||||
_disr_val: int,
|
||||
_n_fields: uint,
|
||||
_name: str/&) -> bool { true }
|
||||
fn visit_leave_enum(_n_variants: uint) -> bool { true }
|
||||
fn visit_leave_enum(_n_variants: uint,
|
||||
_sz: uint, _align: uint) -> bool { true }
|
||||
|
||||
fn visit_iface() -> bool { true }
|
||||
fn visit_enter_res() -> bool { true }
|
||||
fn visit_leave_res() -> bool { true }
|
||||
fn visit_enter_fn(_purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||
fn visit_fn_input(_i: uint, _mode: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_fn_output(_retstyle: uint, _inner: *tydesc) -> bool { true }
|
||||
fn visit_leave_fn(_purity: uint, _proto: uint,
|
||||
_n_inputs: uint, _retstyle: uint) -> bool { true }
|
||||
|
||||
|
||||
fn visit_trait() -> bool { true }
|
||||
fn visit_var() -> bool { true }
|
||||
fn visit_var_integral() -> bool { true }
|
||||
fn visit_param(_i: uint) -> bool { true }
|
||||
fn visit_self() -> bool { true }
|
||||
fn visit_type() -> bool { true }
|
||||
fn visit_opaque_box() -> bool { true }
|
||||
fn visit_enter_constr() -> bool { true }
|
||||
fn visit_leave_constr() -> bool { true }
|
||||
fn visit_constr(_inner: *tydesc) -> bool { true }
|
||||
fn visit_closure_ptr(_ck: uint) -> bool { true }
|
||||
}
|
||||
|
||||
fn visit_ty<T>(v: ty_visitor) {
|
||||
visit_tydesc(get_tydesc::<T>(), v);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let v = my_visitor(@{mut types: ~[]});
|
||||
let vv = v as intrinsic::ty_visitor;
|
||||
let vv = v as ty_visitor;
|
||||
|
||||
intrinsic::visit_ty::<bool>(vv);
|
||||
intrinsic::visit_ty::<int>(vv);
|
||||
intrinsic::visit_ty::<i8>(vv);
|
||||
intrinsic::visit_ty::<i16>(vv);
|
||||
intrinsic::visit_ty::<~[int]>(vv);
|
||||
visit_ty::<bool>(vv);
|
||||
visit_ty::<int>(vv);
|
||||
visit_ty::<i8>(vv);
|
||||
visit_ty::<i16>(vv);
|
||||
visit_ty::<~[int]>(vv);
|
||||
|
||||
for (copy v.types).each {|s|
|
||||
io::println(#fmt("type: %s", s));
|
||||
|
Loading…
x
Reference in New Issue
Block a user