about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-05-10 17:18:04 -0700
committerGraydon Hoare <graydon@mozilla.com>2012-05-10 17:18:04 -0700
commitc23d6a50d786e926d001423f36dc43fe480acbae (patch)
treead2c2fad91816d82340d09c4019961c75611c8b3 /src/rustc
parent664b82a6b79f3aea1d8d00c1e5e7e1e89fcaf71a (diff)
downloadrust-c23d6a50d786e926d001423f36dc43fe480acbae.tar.gz
rust-c23d6a50d786e926d001423f36dc43fe480acbae.zip
Preliminary groundwork for intrinsic module, reflection interface.
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/driver/driver.rs4
-rw-r--r--src/rustc/front/intrinsic.rs140
-rw-r--r--src/rustc/front/intrinsic_inject.rs30
-rw-r--r--src/rustc/middle/trans/native.rs23
-rw-r--r--src/rustc/middle/typeck.rs13
-rw-r--r--src/rustc/rustc.rc1
6 files changed, 211 insertions, 0 deletions
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs
index 6fb525a1346..7f737403da8 100644
--- a/src/rustc/driver/driver.rs
+++ b/src/rustc/driver/driver.rs
@@ -149,6 +149,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));
 
diff --git a/src/rustc/front/intrinsic.rs b/src/rustc/front/intrinsic.rs
new file mode 100644
index 00000000000..e389b30715b
--- /dev/null
+++ b/src/rustc/front/intrinsic.rs
@@ -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);
+    }
+}
diff --git a/src/rustc/front/intrinsic_inject.rs b/src/rustc/front/intrinsic_inject.rs
new file mode 100644
index 00000000000..d2eaf2c8955
--- /dev/null
+++ b/src/rustc/front/intrinsic_inject.rs
@@ -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 }
+}
diff --git a/src/rustc/middle/trans/native.rs b/src/rustc/middle/trans/native.rs
index 77e3a1f3067..4ecbdb7a1c1 100644
--- a/src/rustc/middle/trans/native.rs
+++ b/src/rustc/middle/trans/native.rs
@@ -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);
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 472a4f43e2c..7e132ffbee6 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -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 + "`");
diff --git a/src/rustc/rustc.rc b/src/rustc/rustc.rc
index c50ea26eb15..1f0b7798fe0 100644
--- a/src/rustc/rustc.rc
+++ b/src/rustc/rustc.rc
@@ -76,6 +76,7 @@ mod front {
     mod config;
     mod test;
     mod core_inject;
+    mod intrinsic_inject;
 }
 
 mod back {