Include intrinsic module in all crates, emit visit glue, fn intrinsic::visit_ty. Not yet working.
This commit is contained in:
parent
eab5790c91
commit
9752523f3a
10 changed files with 146 additions and 338 deletions
|
@ -3,144 +3,51 @@
|
|||
|
||||
mod intrinsic {
|
||||
|
||||
// import rusti::visit_ty;
|
||||
// import rusti::visit_val;
|
||||
// import rusti::visit_val_pair;
|
||||
|
||||
export ty_visitor, val_visitor, val_pair_visitor;
|
||||
|
||||
fn macros() {
|
||||
// Present for side-effect of defining intrinsic macros.
|
||||
#macro([#error[f, ...], log(core::error, #fmt[f, ...])]);
|
||||
#macro([#warn[f, ...], log(core::warn, #fmt[f, ...])]);
|
||||
#macro([#info[f, ...], log(core::info, #fmt[f, ...])]);
|
||||
#macro([#debug[f, ...], log(core::debug, #fmt[f, ...])]);
|
||||
}
|
||||
import rusti::visit_ty;
|
||||
export ty_visitor, visit_ty;
|
||||
|
||||
iface ty_visitor {
|
||||
fn visit_bot();
|
||||
fn visit_nil();
|
||||
fn visit_bool();
|
||||
fn visit_bot() -> bool;
|
||||
fn visit_nil() -> bool;
|
||||
fn visit_bool() -> bool;
|
||||
|
||||
fn visit_int();
|
||||
fn visit_i8();
|
||||
fn visit_i16();
|
||||
fn visit_i32();
|
||||
fn visit_i64();
|
||||
fn visit_int() -> bool;
|
||||
fn visit_i8() -> bool;
|
||||
fn visit_i16() -> bool;
|
||||
fn visit_i32() -> bool;
|
||||
fn visit_i64() -> bool;
|
||||
|
||||
fn visit_uint();
|
||||
fn visit_u8();
|
||||
fn visit_u16();
|
||||
fn visit_u32();
|
||||
fn visit_u64();
|
||||
fn visit_uint() -> bool;
|
||||
fn visit_u8() -> bool;
|
||||
fn visit_u16() -> bool;
|
||||
fn visit_u32() -> bool;
|
||||
fn visit_u64() -> bool;
|
||||
|
||||
fn visit_float();
|
||||
fn visit_f32();
|
||||
fn visit_f64();
|
||||
fn visit_float() -> bool;
|
||||
fn visit_f32() -> bool;
|
||||
fn visit_f64() -> bool;
|
||||
|
||||
fn visit_char();
|
||||
fn visit_str();
|
||||
fn visit_char() -> bool;
|
||||
fn visit_str() -> bool;
|
||||
|
||||
fn visit_vec(cells_mut: bool,
|
||||
visit_cell: fn(uint, self));
|
||||
|
||||
fn visit_box(inner_mut: bool,
|
||||
visit_inner: fn(self));
|
||||
|
||||
fn visit_uniq(inner_mut: bool,
|
||||
visit_inner: fn(self));
|
||||
|
||||
fn visit_ptr(inner_mut: bool,
|
||||
visit_inner: fn(self));
|
||||
|
||||
fn visit_rptr(inner_mut: bool,
|
||||
visit_inner: fn(self));
|
||||
|
||||
fn visit_rec(n_fields: uint,
|
||||
field_name: fn(uint) -> str/&,
|
||||
field_mut: fn(uint) -> bool,
|
||||
visit_field: fn(uint, self));
|
||||
fn visit_tup(n_fields: uint,
|
||||
visit_field: fn(uint, self));
|
||||
fn visit_enum(n_variants: uint,
|
||||
variant: uint,
|
||||
variant_name: fn(uint) -> str/&,
|
||||
visit_variant: fn(uint, self));
|
||||
}
|
||||
|
||||
iface val_visitor {
|
||||
|
||||
// Basic types we can visit directly.
|
||||
fn visit_bot();
|
||||
fn visit_nil();
|
||||
fn visit_bool(b: &bool);
|
||||
|
||||
fn visit_int(i: &int);
|
||||
fn visit_i8(i: &i8);
|
||||
fn visit_i16(i: &i16);
|
||||
fn visit_i32(i: &i32);
|
||||
fn visit_i64(i: &i64);
|
||||
|
||||
fn visit_uint(u: &uint);
|
||||
fn visit_u8(i: &i8);
|
||||
fn visit_u16(i: &i16);
|
||||
fn visit_u32(i: &i32);
|
||||
fn visit_u64(i: &i64);
|
||||
|
||||
fn visit_float(f: &float);
|
||||
fn visit_f32(f: &f32);
|
||||
fn visit_f64(f: &f64);
|
||||
|
||||
fn visit_char(c: &char);
|
||||
|
||||
// Vecs and strs we can provide a stub view of.
|
||||
fn visit_str(repr: &vec::unsafe::vec_repr,
|
||||
visit_cell: fn(uint,self));
|
||||
|
||||
fn visit_vec(repr: &vec::unsafe::vec_repr,
|
||||
cells_mut: bool,
|
||||
visit_cell: fn(uint, self));
|
||||
|
||||
fn visit_box(mem: *u8,
|
||||
inner_mut: bool,
|
||||
visit_inner: fn(self));
|
||||
|
||||
fn visit_uniq(mem: *u8,
|
||||
inner_mut: bool,
|
||||
visit_inner: fn(self));
|
||||
|
||||
fn visit_ptr(mem: *u8,
|
||||
inner_mut: bool,
|
||||
visit_inner: fn(self));
|
||||
|
||||
fn visit_rptr(mem: *u8,
|
||||
inner_mut: bool,
|
||||
visit_inner: fn(self));
|
||||
|
||||
// Aggregates we can't really provide anything useful for
|
||||
// beyond a *u8. You really have to know what you're doing.
|
||||
fn visit_rec(mem: *u8,
|
||||
n_fields: uint,
|
||||
field_name: fn(uint) -> str/&,
|
||||
field_mut: fn(uint) -> bool,
|
||||
visit_field: fn(uint, self));
|
||||
fn visit_tup(mem: *u8,
|
||||
n_fields: uint,
|
||||
visit_field: fn(uint, self));
|
||||
fn visit_enum(mem: *u8,
|
||||
n_variants: uint,
|
||||
variant: uint,
|
||||
variant_name: fn(uint) -> str/&,
|
||||
visit_variant: fn(uint, self));
|
||||
}
|
||||
|
||||
iface val_pair_visitor {
|
||||
// FIXME: possibly pair these as enter/leave calls
|
||||
// not just enter with implicit number of subsequent
|
||||
// calls.
|
||||
fn visit_vec_of(mutbl: uint) -> bool;
|
||||
fn visit_box_of(mutbl: uint) -> bool;
|
||||
fn visit_uniq_of(mutbl: uint) -> bool;
|
||||
fn visit_ptr_of(mutbl: uint) -> bool;
|
||||
fn visit_rptr_of(mutbl: uint) -> bool;
|
||||
fn visit_rec_of(n_fields: uint) -> bool;
|
||||
fn visit_rec_field(name: str/&, mutbl: uint) -> bool;
|
||||
fn visit_tup_of(n_fields: uint) -> bool;
|
||||
fn visit_tup_field(mutbl: uint) -> bool;
|
||||
fn visit_enum_of(n_variants: uint) -> bool;
|
||||
fn visit_enum_variant(name: str/&) -> bool;
|
||||
}
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
native mod rusti {
|
||||
// fn visit_ty<T,V:ty_visitor>(tv: V);
|
||||
// fn visit_val<T,V:val_visitor>(v: &T, vv: V);
|
||||
// fn visit_val_pair<T,V:val_pair_visitor>(a: &T, b: &T, vpv: &V);
|
||||
fn visit_ty<T>(&&tv: ty_visitor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,9 @@ export inject_intrinsic;
|
|||
fn inject_intrinsic(sess: session,
|
||||
crate: @ast::crate) -> @ast::crate {
|
||||
|
||||
// FIXME: upgrade this to #include_str("intrinsic.rs");
|
||||
let intrinsic_module = @"mod intrinsic { }";
|
||||
let intrinsic_module = @#include_str("intrinsic.rs");
|
||||
|
||||
let item = parse::parse_item_from_source_str("intrinsic",
|
||||
let item = parse::parse_item_from_source_str("<intrinsic>",
|
||||
intrinsic_module,
|
||||
sess.opts.cfg,
|
||||
[], ast::public,
|
||||
|
|
|
@ -641,13 +641,10 @@ 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;
|
||||
alt bcx.ccx().intrinsic_ifaces.find("visit_ty") {
|
||||
some(iid) {
|
||||
bcx = reflect::emit_calls_to_iface_visit_ty(bcx, t, v, iid);
|
||||
}
|
||||
none {
|
||||
}
|
||||
}
|
||||
assert bcx.ccx().tcx.intrinsic_ifaces.contains_key("ty_visitor");
|
||||
let (iid, ty) = bcx.ccx().tcx.intrinsic_ifaces.get("ty_visitor");
|
||||
let v = PointerCast(bcx, v, T_ptr(type_of::type_of(bcx.ccx(), ty)));
|
||||
bcx = reflect::emit_calls_to_iface_visit_ty(bcx, t, Load(bcx, v), iid);
|
||||
build_return(bcx);
|
||||
}
|
||||
|
||||
|
@ -1073,6 +1070,7 @@ fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
|
|||
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti);
|
||||
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti);
|
||||
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, static_ti);
|
||||
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_visit_glue, static_ti);
|
||||
}
|
||||
|
||||
fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
|
||||
|
@ -5302,7 +5300,6 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
|
|||
tn: tn,
|
||||
externs: str_hash::<ValueRef>(),
|
||||
intrinsics: intrinsics,
|
||||
intrinsic_ifaces: reflect::find_intrinsic_ifaces(crate),
|
||||
item_vals: int_hash::<ValueRef>(),
|
||||
exp_map: emap,
|
||||
reachable: reachable,
|
||||
|
|
|
@ -72,7 +72,6 @@ type crate_ctxt = {
|
|||
tn: type_names,
|
||||
externs: hashmap<str, ValueRef>,
|
||||
intrinsics: hashmap<str, ValueRef>,
|
||||
intrinsic_ifaces: hashmap<str, ast::def_id>,
|
||||
item_vals: hashmap<ast::node_id, ValueRef>,
|
||||
exp_map: resolve::exp_map,
|
||||
reachable: reachable::map,
|
||||
|
|
|
@ -836,53 +836,8 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
|
|||
}
|
||||
"visit_ty" {
|
||||
let tp_ty = substs.tys[0];
|
||||
let vp_ty = substs.tys[1];
|
||||
let visitor = get_param(decl, first_real_arg);
|
||||
|
||||
alt impl::find_vtable_in_fn_ctxt(substs,
|
||||
1u, /* n_param */
|
||||
0u /* n_bound */ ) {
|
||||
|
||||
typeck::vtable_iface(iid, _) {
|
||||
bcx = reflect::emit_calls_to_iface_visit_ty(bcx, tp_ty,
|
||||
visitor, iid);
|
||||
}
|
||||
|
||||
// This case is a slightly weird and possibly redundant path in
|
||||
// which we monomorphize the reflection interface. FIXME:
|
||||
// possibly remove this, it might be overkill.
|
||||
typeck::vtable_static(impl_did, impl_substs, sub_origins) {
|
||||
reflect::visit_ty_steps(bcx, tp_ty) {|mth_name, args|
|
||||
let mth_id = impl::method_with_name(ccx, impl_did, mth_name);
|
||||
let mth_ty = ty::lookup_item_type(ccx.tcx, mth_id).ty;
|
||||
// FIXME: is this safe? There is no callee AST node,
|
||||
// we're synthesizing it.
|
||||
let callee_id = (-1) as ast::node_id;
|
||||
let get_lval = {|bcx|
|
||||
let lval = lval_static_fn_inner(bcx, mth_id, callee_id,
|
||||
impl_substs,
|
||||
some(sub_origins));
|
||||
{env: self_env(visitor, vp_ty, none) with lval}
|
||||
};
|
||||
bcx = trans_call_inner(
|
||||
bcx, none, mth_ty, ty::mk_bool(ccx.tcx),
|
||||
get_lval, arg_vals(args), ignore);
|
||||
}
|
||||
}
|
||||
|
||||
_ {
|
||||
ccx.sess.span_bug(item.span,
|
||||
"non-static callee in 'visit_ty' intrinsinc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"visit_val" {
|
||||
bcx.sess().unimpl("trans::native::visit_val");
|
||||
}
|
||||
|
||||
"visit_val_pair" {
|
||||
bcx.sess().unimpl("trans::native::visit_val_pair");
|
||||
call_tydesc_glue(bcx, visitor, tp_ty, abi::tydesc_field_visit_glue);
|
||||
}
|
||||
}
|
||||
build_return(bcx);
|
||||
|
|
|
@ -10,27 +10,40 @@ import type_of::*;
|
|||
import ast::def_id;
|
||||
import util::ppaux::ty_to_str;
|
||||
|
||||
fn visit_ty_steps<T>(bcx: block, t: ty::t,
|
||||
step: fn(tyname: str, args: [ValueRef]) -> T) -> T {
|
||||
fn visit_ty_steps(bcx: block, t: ty::t,
|
||||
step: fn(bcx: block,
|
||||
tyname: str,
|
||||
args: [ValueRef]) -> block,
|
||||
sub: fn(bcx: block, t: ty::t) -> block) -> block {
|
||||
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_bot { step("visit_bot", []) }
|
||||
ty::ty_nil { step("visit_nil", []) }
|
||||
ty::ty_bool { step("visit_bool", []) }
|
||||
ty::ty_int(ast::ty_i) { step("visit_int", []) }
|
||||
ty::ty_int(ast::ty_char) { step("visit_char", []) }
|
||||
ty::ty_int(ast::ty_i8) { step("visit_i8", []) }
|
||||
ty::ty_int(ast::ty_i16) { step("visit_i16", []) }
|
||||
ty::ty_int(ast::ty_i32) { step("visit_i32", []) }
|
||||
ty::ty_int(ast::ty_i64) { step("visit_i64", []) }
|
||||
ty::ty_uint(ast::ty_u) { step("visit_uint", []) }
|
||||
ty::ty_uint(ast::ty_u8) { step("visit_u8", []) }
|
||||
ty::ty_uint(ast::ty_u16) { step("visit_u16", []) }
|
||||
ty::ty_uint(ast::ty_u32) { step("visit_u32", []) }
|
||||
ty::ty_uint(ast::ty_u64) { step("visit_u64", []) }
|
||||
ty::ty_float(ast::ty_f) { step("visit_float", []) }
|
||||
ty::ty_float(ast::ty_f32) { step("visit_f32", []) }
|
||||
ty::ty_float(ast::ty_f64) { step("visit_f64", []) }
|
||||
ty::ty_str { step("visit_str", []) }
|
||||
ty::ty_bot { step(bcx, "visit_bot", []) }
|
||||
ty::ty_nil { step(bcx, "visit_nil", []) }
|
||||
ty::ty_bool { step(bcx, "visit_bool", []) }
|
||||
ty::ty_int(ast::ty_i) { step(bcx, "visit_int", []) }
|
||||
ty::ty_int(ast::ty_char) { step(bcx, "visit_char", []) }
|
||||
ty::ty_int(ast::ty_i8) { step(bcx, "visit_i8", []) }
|
||||
ty::ty_int(ast::ty_i16) { step(bcx, "visit_i16", []) }
|
||||
ty::ty_int(ast::ty_i32) { step(bcx, "visit_i32", []) }
|
||||
ty::ty_int(ast::ty_i64) { step(bcx, "visit_i64", []) }
|
||||
ty::ty_uint(ast::ty_u) { step(bcx, "visit_uint", []) }
|
||||
ty::ty_uint(ast::ty_u8) { step(bcx, "visit_u8", []) }
|
||||
ty::ty_uint(ast::ty_u16) { step(bcx, "visit_u16", []) }
|
||||
ty::ty_uint(ast::ty_u32) { step(bcx, "visit_u32", []) }
|
||||
ty::ty_uint(ast::ty_u64) { step(bcx, "visit_u64", []) }
|
||||
ty::ty_float(ast::ty_f) { step(bcx, "visit_float", []) }
|
||||
ty::ty_float(ast::ty_f32) { step(bcx, "visit_f32", []) }
|
||||
ty::ty_float(ast::ty_f64) { step(bcx, "visit_f64", []) }
|
||||
ty::ty_str { step(bcx, "visit_str", []) }
|
||||
|
||||
ty::ty_vec(mt) {
|
||||
let bcx = step(bcx, "visit_vec_of",
|
||||
[C_uint(ccx, mt.mutbl as uint)]);
|
||||
sub(bcx, mt.ty)
|
||||
}
|
||||
|
||||
_ {
|
||||
bcx.sess().unimpl("trans::reflect::visit_ty_args on "
|
||||
+ ty_to_str(bcx.ccx().tcx, t));
|
||||
|
@ -43,51 +56,20 @@ fn emit_calls_to_iface_visit_ty(bcx: block, t: ty::t,
|
|||
visitor_val: ValueRef,
|
||||
visitor_iid: def_id) -> block {
|
||||
let tcx = bcx.tcx();
|
||||
visit_ty_steps(bcx, t) {|mth_name, args|
|
||||
let methods = ty::iface_methods(tcx, visitor_iid);
|
||||
let mth_idx = option::get(ty::method_idx(mth_name, *methods));
|
||||
let mth_ty = ty::mk_fn(tcx, methods[mth_idx].fty);
|
||||
let get_lval = {|bcx|
|
||||
impl::trans_iface_callee(bcx, visitor_val, mth_ty, mth_idx)
|
||||
};
|
||||
trans_call_inner(bcx, none, mth_ty, ty::mk_bool(tcx),
|
||||
get_lval, arg_vals(args), ignore)
|
||||
}
|
||||
let methods = ty::iface_methods(tcx, visitor_iid);
|
||||
visit_ty_steps(bcx, t,
|
||||
{|bcx, mth_name, args|
|
||||
let mth_idx = option::get(ty::method_idx(mth_name,
|
||||
*methods));
|
||||
let mth_ty = ty::mk_fn(tcx, methods[mth_idx].fty);
|
||||
let get_lval = {|bcx|
|
||||
impl::trans_iface_callee(bcx, visitor_val,
|
||||
mth_ty, mth_idx)
|
||||
};
|
||||
trans_call_inner(bcx, none, mth_ty, ty::mk_bool(tcx),
|
||||
get_lval, arg_vals(args), ignore)
|
||||
},
|
||||
{|bcx, t_sub|
|
||||
call_tydesc_glue(bcx, visitor_val, t_sub,
|
||||
abi::tydesc_field_visit_glue)})
|
||||
}
|
||||
|
||||
|
||||
fn find_intrinsic_ifaces(crate: @ast::crate)
|
||||
-> hashmap<str, ast::def_id> {
|
||||
|
||||
let ifaces : hashmap<str, ast::def_id> = str_hash();
|
||||
|
||||
// FIXME: hooking into the "intrinsic" root module is crude.
|
||||
// there ought to be a better approach. Attributes?
|
||||
|
||||
for crate.node.module.items.each {|crate_item|
|
||||
if crate_item.ident == "intrinsic" {
|
||||
alt crate_item.node {
|
||||
ast::item_mod(m) {
|
||||
for m.items.each {|intrinsic_item|
|
||||
alt intrinsic_item.node {
|
||||
ast::item_iface(_, _, _) {
|
||||
let def_id = { crate: ast::local_crate,
|
||||
node: intrinsic_item.id };
|
||||
ifaces.insert(intrinsic_item.ident,
|
||||
def_id);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Assert whatever ifaces we are expecting to get from mod intrinsic.
|
||||
// assert ifaces.contains_key("visit_ty");
|
||||
|
||||
ret ifaces;
|
||||
}
|
|
@ -76,7 +76,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
|
|||
ast_map::node_native_item(i@@{node: native_item_fn(_, _), _}, abi, _) {
|
||||
if abi == native_abi_rust_intrinsic {
|
||||
let flags = alt check i.ident {
|
||||
"visit_ty" | "visit_val" | "visit_val_pair" { 3u }
|
||||
"visit_ty" { 3u }
|
||||
"size_of" | "pref_align_of" | "min_align_of" |
|
||||
"init" | "reinterpret_cast" { use_repr }
|
||||
"get_tydesc" | "needs_drop" { use_tydesc }
|
||||
|
|
|
@ -220,6 +220,7 @@ type ctxt =
|
|||
node_type_substs: hashmap<node_id, [t]>,
|
||||
|
||||
items: ast_map::map,
|
||||
intrinsic_ifaces: hashmap<str, (ast::def_id, t)>,
|
||||
freevars: freevars::freevar_map,
|
||||
tcache: type_cache,
|
||||
rcache: creader_cache,
|
||||
|
@ -473,6 +474,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_ifaces: map::str_hash(),
|
||||
freevars: freevars,
|
||||
tcache: new_def_hash(),
|
||||
rcache: mk_rcache(),
|
||||
|
|
|
@ -24,6 +24,34 @@ import astconv::{type_rscope, empty_rscope, in_binding_rscope, ast_conv,
|
|||
ty_of_fn_decl, ty_of_arg, region_scope, ast_ty_to_ty};
|
||||
|
||||
fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
|
||||
|
||||
// FIXME: hooking into the "intrinsic" root module is crude.
|
||||
// there ought to be a better approach. Attributes?
|
||||
|
||||
for crate.node.module.items.each {|crate_item|
|
||||
if crate_item.ident == "intrinsic" {
|
||||
alt crate_item.node {
|
||||
ast::item_mod(m) {
|
||||
for m.items.each {|intrinsic_item|
|
||||
alt intrinsic_item.node {
|
||||
ast::item_iface(_, _, _) {
|
||||
let def_id = { crate: ast::local_crate,
|
||||
node: intrinsic_item.id };
|
||||
let substs = {self_r: none, self_ty: none, tps: []};
|
||||
let ty = ty::mk_iface(ccx.tcx, def_id, substs);
|
||||
ccx.tcx.intrinsic_ifaces.insert
|
||||
(intrinsic_item.ident, (def_id, ty));
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
|
||||
visit_item: bind convert(ccx, _),
|
||||
visit_native_item: bind convert_native(ccx, _)
|
||||
|
@ -461,17 +489,11 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::native_item) {
|
|||
ty::mk_imm_ptr(tcx, param(ccx, 0u))) }
|
||||
"needs_drop" { (1u, [], ty::mk_bool(tcx)) }
|
||||
|
||||
"visit_ty" { (2u, [arg(ast::by_ref, param(ccx, 1u))],
|
||||
ty::mk_nil(tcx)) }
|
||||
|
||||
"visit_val" { (2u, [arg(ast::by_ref, param(ccx, 0u)),
|
||||
arg(ast::by_ref, param(ccx, 1u))],
|
||||
ty::mk_nil(tcx)) }
|
||||
|
||||
"visit_val_pair" { (2u, [arg(ast::by_ref, param(ccx, 0u)),
|
||||
arg(ast::by_ref, param(ccx, 0u)),
|
||||
arg(ast::by_ref, param(ccx, 1u))],
|
||||
ty::mk_nil(tcx)) }
|
||||
"visit_ty" {
|
||||
assert ccx.tcx.intrinsic_ifaces.contains_key("ty_visitor");
|
||||
let (_, visitor_iface) = ccx.tcx.intrinsic_ifaces.get("ty_visitor");
|
||||
(1u, [arg(ast::by_ref, visitor_iface)], ty::mk_nil(tcx))
|
||||
}
|
||||
|
||||
other {
|
||||
tcx.sess.span_err(it.span, "unrecognized intrinsic function: `" +
|
||||
|
|
|
@ -1,54 +1,12 @@
|
|||
// xfail-test
|
||||
//
|
||||
// This works on stage2 currently. Once we have a snapshot
|
||||
// and some fiddling with inject_intrinsic (and possibly another
|
||||
// snapshot after _that_) it can be un-xfailed and changed
|
||||
// to use the intrinsic:: interface and native module.
|
||||
//
|
||||
// This doesn't work quite yet. There's something wrong with the callback
|
||||
// type when dispatching through the visit_glue. Get a GEP crash on the
|
||||
// callee.
|
||||
|
||||
iface ty_visitor {
|
||||
fn visit_bot() -> bool;
|
||||
fn visit_nil() -> bool;
|
||||
fn visit_bool() -> bool;
|
||||
enum my_visitor = @{ mut types: [str] };
|
||||
|
||||
fn visit_int() -> bool;
|
||||
fn visit_i8() -> bool;
|
||||
fn visit_i16() -> bool;
|
||||
fn visit_i32() -> bool;
|
||||
fn visit_i64() -> bool;
|
||||
|
||||
fn visit_uint() -> bool;
|
||||
fn visit_u8() -> bool;
|
||||
fn visit_u16() -> bool;
|
||||
fn visit_u32() -> bool;
|
||||
fn visit_u64() -> bool;
|
||||
|
||||
fn visit_float() -> bool;
|
||||
fn visit_f32() -> bool;
|
||||
fn visit_f64() -> bool;
|
||||
|
||||
fn visit_char() -> bool;
|
||||
fn visit_str() -> bool;
|
||||
|
||||
// FIXME: possibly pair these as enter/leave calls
|
||||
// not just enter with implicit number of subsequent
|
||||
// calls.
|
||||
fn visit_vec_of(is_mut: bool) -> bool;
|
||||
fn visit_box_of(is_mut: bool) -> bool;
|
||||
fn visit_uniq_of(is_mut: bool) -> bool;
|
||||
fn visit_ptr_of(is_mut: bool) -> bool;
|
||||
fn visit_rptr_of(is_mut: bool) -> bool;
|
||||
fn visit_rec_of(n_fields: uint) -> bool;
|
||||
fn visit_rec_field(name: str/&, is_mut: bool) -> bool;
|
||||
fn visit_tup_of(n_fields: uint) -> bool;
|
||||
fn visit_tup_field(is_mut: bool) -> bool;
|
||||
fn visit_enum_of(n_variants: uint) -> bool;
|
||||
fn visit_enum_variant(name: str/&) -> bool;
|
||||
}
|
||||
|
||||
enum my_visitor = { mut types: [str] };
|
||||
|
||||
impl of ty_visitor for my_visitor {
|
||||
impl of intrinsic::ty_visitor for my_visitor {
|
||||
fn visit_bot() -> bool {
|
||||
self.types += ["bot"];
|
||||
#error("visited bot type");
|
||||
|
@ -95,43 +53,30 @@ impl of ty_visitor for my_visitor {
|
|||
fn visit_char() -> bool { true }
|
||||
fn visit_str() -> bool { true }
|
||||
|
||||
fn visit_vec_of(_is_mut: bool) -> bool { true }
|
||||
fn visit_box_of(_is_mut: bool) -> bool { true }
|
||||
fn visit_uniq_of(_is_mut: bool) -> bool { true }
|
||||
fn visit_ptr_of(_is_mut: bool) -> bool { true }
|
||||
fn visit_rptr_of(_is_mut: bool) -> bool { true }
|
||||
fn visit_vec_of(_mutbl: uint) -> bool { true }
|
||||
fn visit_box_of(_mutbl: uint) -> bool { true }
|
||||
fn visit_uniq_of(_mutbl: uint) -> bool { true }
|
||||
fn visit_ptr_of(_mutbl: uint) -> bool { true }
|
||||
fn visit_rptr_of(_mutbl: uint) -> bool { true }
|
||||
fn visit_rec_of(_n_fields: uint) -> bool { true }
|
||||
fn visit_rec_field(_name: str/&, _is_mut: bool) -> bool { true }
|
||||
fn visit_rec_field(_name: str/&, _mutbl: uint) -> bool { true }
|
||||
fn visit_tup_of(_n_fields: uint) -> bool { true }
|
||||
fn visit_tup_field(_is_mut: bool) -> bool { true }
|
||||
fn visit_tup_field(_mutbl: uint) -> bool { true }
|
||||
fn visit_enum_of(_n_variants: uint) -> bool { true }
|
||||
fn visit_enum_variant(_name: str/&) -> bool { true }
|
||||
}
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
native mod rusti {
|
||||
fn visit_ty<T,V:ty_visitor>(tv: V);
|
||||
}
|
||||
|
||||
fn via_iface(v: ty_visitor) {
|
||||
rusti::visit_ty::<bool,ty_visitor>(v);
|
||||
rusti::visit_ty::<int,ty_visitor>(v);
|
||||
rusti::visit_ty::<i8,ty_visitor>(v);
|
||||
rusti::visit_ty::<i16,ty_visitor>(v);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let v = my_visitor({mut types: []});
|
||||
let v = my_visitor(@{mut types: []});
|
||||
let vv = v as intrinsic::ty_visitor;
|
||||
|
||||
rusti::visit_ty::<bool,my_visitor>(v);
|
||||
rusti::visit_ty::<int,my_visitor>(v);
|
||||
rusti::visit_ty::<i8,my_visitor>(v);
|
||||
rusti::visit_ty::<i16,my_visitor>(v);
|
||||
intrinsic::visit_ty::<bool>(vv);
|
||||
intrinsic::visit_ty::<int>(vv);
|
||||
intrinsic::visit_ty::<i8>(vv);
|
||||
intrinsic::visit_ty::<i16>(vv);
|
||||
|
||||
for v.types.each {|s|
|
||||
io::println(#fmt("type: %s", s));
|
||||
}
|
||||
assert v.types == ["bool", "int", "i8", "i16"];
|
||||
|
||||
via_iface(v as ty_visitor);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue