Preliminary groundwork for intrinsic module, reflection interface.

This commit is contained in:
Graydon Hoare
2012-05-10 17:18:04 -07:00
parent 664b82a6b7
commit c23d6a50d7
11 changed files with 291 additions and 0 deletions

View File

@@ -148,6 +148,10 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
if upto == cu_expand { ret {crate: crate, tcx: none}; }
crate =
time(time_passes, "intrinsic injection",
bind front::intrinsic_inject::inject_intrinsic(sess, crate));
crate =
time(time_passes, "core injection",
bind front::core_inject::maybe_inject_libcore_ref(sess, crate));

View File

@@ -0,0 +1,140 @@
// NB: this file is #include_str'ed into the compiler, re-parsed
// and injected into each crate the compiler builds. Keep it small.
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, ...])]);
}
iface ty_visitor {
fn visit_nil();
fn visit_bool();
fn visit_int();
fn visit_i8();
fn visit_i16();
fn visit_i32();
fn visit_i64();
fn visit_uint();
fn visit_u8();
fn visit_u16();
fn visit_u32();
fn visit_u64();
fn visit_float();
fn visit_f32();
fn visit_f64();
fn visit_str();
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_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);
// 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 {
}
#[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);
}
}

View File

@@ -0,0 +1,30 @@
import driver::session::session;
import syntax::parse;
import syntax::ast;
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 item = parse::parse_item_from_source_str("intrinsic",
intrinsic_module,
sess.opts.cfg,
[], ast::public,
sess.parse_sess);
let item =
alt item {
some(i) { i }
none {
sess.fatal("no item found in intrinsic module");
}
};
let items = [item] + crate.node.module.items;
ret @{node: {module: { items: items with crate.node.module }
with crate.node} with *crate }
}

View File

@@ -834,6 +834,29 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
Store(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)),
fcx.llretptr);
}
"visit_ty" {
let vp_ty = substs.tys[1], _llvp_ty = type_of::type_of(ccx, vp_ty);
let visitor = get_param(decl, first_real_arg);
// FIXME: implement a proper iface-call. Nontrivial.
Call(bcx, visitor, []);
}
"visit_val" {
let vp_ty = substs.tys[1], _llvp_ty = type_of::type_of(ccx, vp_ty);
let val = get_param(decl, first_real_arg);
let visitor = get_param(decl, first_real_arg + 1u);
// FIXME: implement a proper iface-call. Nontrivial.
Call(bcx, visitor, [val]);
}
"visit_val_pair" {
let vp_ty = substs.tys[1], _llvp_ty = type_of::type_of(ccx, vp_ty);
let a = get_param(decl, first_real_arg);
let b = get_param(decl, first_real_arg + 1u);
let visitor = get_param(decl, first_real_arg + 2u);
// FIXME: implement a proper iface-call. Nontrivial.
Call(bcx, visitor, [a, b]);
}
}
build_return(bcx);
finish_fn(fcx, lltop);

View File

@@ -2072,6 +2072,19 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::native_item) {
"addr_of" { (1u, [arg(ast::by_ref, param(ccx, 0u))],
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)) }
other {
tcx.sess.span_err(it.span, "unrecognized intrinsic function: `" +
other + "`");

View File

@@ -76,6 +76,7 @@ mod front {
mod config;
mod test;
mod core_inject;
mod intrinsic_inject;
}
mod back {