2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-01-07 16:16:52 -06:00
|
|
|
|
2012-09-04 13:54:36 -05:00
|
|
|
use back::abi;
|
2012-12-13 15:05:22 -06:00
|
|
|
use lib::llvm::{TypeRef, ValueRef};
|
|
|
|
use middle::trans::base::*;
|
|
|
|
use middle::trans::build::*;
|
|
|
|
use middle::trans::callee::{ArgVals, DontAutorefArg};
|
2012-12-23 16:41:37 -06:00
|
|
|
use middle::trans::callee;
|
2012-12-13 15:05:22 -06:00
|
|
|
use middle::trans::common::*;
|
|
|
|
use middle::trans::datum::*;
|
|
|
|
use middle::trans::expr::SaveIn;
|
2012-12-23 16:41:37 -06:00
|
|
|
use middle::trans::glue;
|
2013-01-30 13:46:19 -06:00
|
|
|
use middle::trans::machine;
|
2012-12-23 16:41:37 -06:00
|
|
|
use middle::trans::meth;
|
2012-12-13 15:05:22 -06:00
|
|
|
use middle::trans::type_of::*;
|
2012-09-04 13:54:36 -05:00
|
|
|
use util::ppaux::ty_to_str;
|
2012-12-13 15:05:22 -06:00
|
|
|
|
2013-02-01 01:13:36 -06:00
|
|
|
use std::oldmap::HashMap;
|
2012-12-13 15:05:22 -06:00
|
|
|
use syntax::ast::def_id;
|
|
|
|
use syntax::ast;
|
2012-05-14 19:57:39 -05:00
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
pub struct Reflector {
|
2012-06-07 15:51:35 -05:00
|
|
|
visitor_val: ValueRef,
|
2012-06-29 18:26:56 -05:00
|
|
|
visitor_methods: @~[ty::method],
|
2012-06-19 20:35:56 -05:00
|
|
|
final_bcx: block,
|
|
|
|
tydesc_ty: TypeRef,
|
2013-02-04 16:02:01 -06:00
|
|
|
bcx: block
|
|
|
|
}
|
2012-05-16 20:24:00 -05:00
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
pub impl Reflector {
|
|
|
|
fn c_uint(&mut self, u: uint) -> ValueRef {
|
2012-06-07 21:42:22 -05:00
|
|
|
C_uint(self.bcx.ccx(), u)
|
2012-06-07 15:51:35 -05:00
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn c_int(&mut self, i: int) -> ValueRef {
|
2012-06-08 17:35:55 -05:00
|
|
|
C_int(self.bcx.ccx(), i)
|
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn c_slice(&mut self, +s: ~str) -> ValueRef {
|
2013-01-05 01:06:25 -06:00
|
|
|
// We're careful to not use first class aggregates here because that
|
|
|
|
// will kick us off fast isel. (Issue #4352.)
|
|
|
|
let bcx = self.bcx;
|
|
|
|
let str_vstore = ty::vstore_slice(ty::re_static);
|
|
|
|
let str_ty = ty::mk_estr(bcx.tcx(), str_vstore);
|
|
|
|
let scratch = scratch_datum(bcx, str_ty, false);
|
2013-01-07 16:16:52 -06:00
|
|
|
let len = C_uint(bcx.ccx(), s.len() + 1);
|
2013-01-05 01:06:25 -06:00
|
|
|
let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), T_ptr(T_i8()));
|
|
|
|
Store(bcx, c_str, GEPi(bcx, scratch.val, [ 0, 0 ]));
|
|
|
|
Store(bcx, len, GEPi(bcx, scratch.val, [ 0, 1 ]));
|
|
|
|
scratch.val
|
2012-06-08 18:41:38 -05:00
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn c_size_and_align(&mut self, t: ty::t) -> ~[ValueRef] {
|
2012-06-11 20:33:58 -05:00
|
|
|
let tr = type_of::type_of(self.bcx.ccx(), t);
|
2013-01-30 13:46:19 -06:00
|
|
|
let s = machine::llsize_of_real(self.bcx.ccx(), tr);
|
|
|
|
let a = machine::llalign_of_min(self.bcx.ccx(), tr);
|
2012-08-01 19:30:05 -05:00
|
|
|
return ~[self.c_uint(s),
|
2012-06-29 18:26:56 -05:00
|
|
|
self.c_uint(a)];
|
2012-06-11 20:33:58 -05:00
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn c_tydesc(&mut self, t: ty::t) -> ValueRef {
|
2012-06-19 20:35:56 -05:00
|
|
|
let bcx = self.bcx;
|
2012-07-10 17:25:58 -05:00
|
|
|
let static_ti = get_tydesc(bcx.ccx(), t);
|
2012-08-28 17:54:45 -05:00
|
|
|
glue::lazily_emit_all_tydesc_glue(bcx.ccx(), static_ti);
|
2012-07-10 17:25:58 -05:00
|
|
|
PointerCast(bcx, static_ti.tydesc, T_ptr(self.tydesc_ty))
|
2012-06-19 20:35:56 -05:00
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn c_mt(&mut self, mt: ty::mt) -> ~[ValueRef] {
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(mt.mutbl as uint),
|
|
|
|
self.c_tydesc(mt.ty)]
|
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn visit(&mut self, ty_name: ~str, args: ~[ValueRef]) {
|
2012-06-07 21:42:22 -05:00
|
|
|
let tcx = self.bcx.tcx();
|
2012-12-10 15:47:54 -06:00
|
|
|
let mth_idx = ty::method_idx(
|
2012-07-18 18:18:02 -05:00
|
|
|
tcx.sess.ident_of(~"visit_" + ty_name),
|
2012-12-10 15:47:54 -06:00
|
|
|
*self.visitor_methods).expect(fmt!("Couldn't find visit method \
|
|
|
|
for %s", ty_name));
|
2013-01-31 19:12:29 -06:00
|
|
|
let mth_ty =
|
|
|
|
ty::mk_bare_fn(tcx, copy self.visitor_methods[mth_idx].fty);
|
2012-06-07 15:51:35 -05:00
|
|
|
let v = self.visitor_val;
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("passing %u args:", vec::len(args));
|
2012-06-08 18:41:38 -05:00
|
|
|
let bcx = self.bcx;
|
2012-06-30 18:19:07 -05:00
|
|
|
for args.eachi |i, a| {
|
2012-09-21 20:43:30 -05:00
|
|
|
debug!("arg %u: %s", i, val_str(bcx.ccx().tn, *a));
|
2012-06-08 18:41:38 -05:00
|
|
|
}
|
2012-08-28 17:54:45 -05:00
|
|
|
let bool_ty = ty::mk_bool(tcx);
|
|
|
|
let scratch = scratch_datum(bcx, bool_ty, false);
|
2012-10-05 18:55:42 -05:00
|
|
|
// XXX: Should not be vstore_box!
|
2012-08-28 17:54:45 -05:00
|
|
|
let bcx = callee::trans_call_inner(
|
|
|
|
self.bcx, None, mth_ty, bool_ty,
|
2012-11-28 19:33:30 -06:00
|
|
|
|bcx| meth::trans_trait_callee_from_llval(bcx,
|
|
|
|
mth_ty,
|
|
|
|
mth_idx,
|
|
|
|
v,
|
|
|
|
ty::vstore_box,
|
2013-01-28 20:10:34 -06:00
|
|
|
ast::sty_region(
|
|
|
|
ast::m_imm)),
|
2012-09-19 20:00:26 -05:00
|
|
|
ArgVals(args), SaveIn(scratch.val), DontAutorefArg);
|
2012-08-28 17:54:45 -05:00
|
|
|
let result = scratch.to_value_llval(bcx);
|
2013-02-06 16:28:02 -06:00
|
|
|
let result = bool_to_i1(bcx, result);
|
2012-07-14 00:57:48 -05:00
|
|
|
let next_bcx = sub_block(bcx, ~"next");
|
2012-08-28 17:54:45 -05:00
|
|
|
CondBr(bcx, result, next_bcx.llbb, self.final_bcx.llbb);
|
2012-06-19 20:35:56 -05:00
|
|
|
self.bcx = next_bcx
|
2012-06-07 15:51:35 -05:00
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn bracketed(&mut self,
|
|
|
|
bracket_name: ~str,
|
|
|
|
+extra: ~[ValueRef],
|
|
|
|
inner: &fn()) {
|
2013-01-07 16:16:52 -06:00
|
|
|
// XXX: Bad copy.
|
|
|
|
self.visit(~"enter_" + bracket_name, copy extra);
|
2012-06-19 20:35:56 -05:00
|
|
|
inner();
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"leave_" + bracket_name, extra);
|
2012-06-08 15:26:06 -05:00
|
|
|
}
|
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn vstore_name_and_extra(&mut self,
|
|
|
|
t: ty::t,
|
2012-06-14 21:53:56 -05:00
|
|
|
vstore: ty::vstore,
|
2013-01-07 16:16:52 -06:00
|
|
|
f: fn(+s: ~str,+v: ~[ValueRef])) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match vstore {
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::vstore_fixed(n) => {
|
2012-06-29 18:26:56 -05:00
|
|
|
let extra = vec::append(~[self.c_uint(n)],
|
2012-06-28 17:00:03 -05:00
|
|
|
self.c_size_and_align(t));
|
2012-07-14 00:57:48 -05:00
|
|
|
f(~"fixed", extra)
|
2012-06-14 21:53:56 -05:00
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::vstore_slice(_) => f(~"slice", ~[]),
|
|
|
|
ty::vstore_uniq => f(~"uniq", ~[]),
|
|
|
|
ty::vstore_box => f(~"box", ~[])
|
2012-06-07 15:51:35 -05:00
|
|
|
}
|
|
|
|
}
|
2012-05-16 20:24:00 -05:00
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn leaf(&mut self, +name: ~str) {
|
2012-06-29 18:26:56 -05:00
|
|
|
self.visit(name, ~[]);
|
2012-06-07 15:51:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Entrypoint
|
2013-02-04 16:02:01 -06:00
|
|
|
fn visit_ty(&mut self, t: ty::t) {
|
2012-06-08 15:26:06 -05:00
|
|
|
let bcx = self.bcx;
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("reflect::visit_ty %s",
|
|
|
|
ty_to_str(bcx.ccx().tcx, t));
|
2012-06-08 15:26:06 -05:00
|
|
|
|
2013-01-07 16:16:52 -06:00
|
|
|
match /*bad*/copy ty::get(t).sty {
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::ty_bot => self.leaf(~"bot"),
|
|
|
|
ty::ty_nil => self.leaf(~"nil"),
|
|
|
|
ty::ty_bool => self.leaf(~"bool"),
|
|
|
|
ty::ty_int(ast::ty_i) => self.leaf(~"int"),
|
|
|
|
ty::ty_int(ast::ty_char) => self.leaf(~"char"),
|
|
|
|
ty::ty_int(ast::ty_i8) => self.leaf(~"i8"),
|
|
|
|
ty::ty_int(ast::ty_i16) => self.leaf(~"i16"),
|
|
|
|
ty::ty_int(ast::ty_i32) => self.leaf(~"i32"),
|
|
|
|
ty::ty_int(ast::ty_i64) => self.leaf(~"i64"),
|
|
|
|
ty::ty_uint(ast::ty_u) => self.leaf(~"uint"),
|
|
|
|
ty::ty_uint(ast::ty_u8) => self.leaf(~"u8"),
|
|
|
|
ty::ty_uint(ast::ty_u16) => self.leaf(~"u16"),
|
|
|
|
ty::ty_uint(ast::ty_u32) => self.leaf(~"u32"),
|
|
|
|
ty::ty_uint(ast::ty_u64) => self.leaf(~"u64"),
|
|
|
|
ty::ty_float(ast::ty_f) => self.leaf(~"float"),
|
|
|
|
ty::ty_float(ast::ty_f32) => self.leaf(~"f32"),
|
|
|
|
ty::ty_float(ast::ty_f64) => self.leaf(~"f64"),
|
2012-06-07 15:51:35 -05:00
|
|
|
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::ty_unboxed_vec(mt) => self.visit(~"vec", self.c_mt(mt)),
|
|
|
|
ty::ty_estr(vst) => {
|
2012-06-30 18:19:07 -05:00
|
|
|
do self.vstore_name_and_extra(t, vst) |name, extra| {
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"estr_" + name, extra)
|
2012-06-07 15:51:35 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::ty_evec(mt, vst) => {
|
2012-06-30 18:19:07 -05:00
|
|
|
do self.vstore_name_and_extra(t, vst) |name, extra| {
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"evec_" + name, extra +
|
2012-06-19 20:35:56 -05:00
|
|
|
self.c_mt(mt))
|
2012-06-07 15:51:35 -05:00
|
|
|
}
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
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)),
|
2012-06-07 15:51:35 -05:00
|
|
|
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::ty_rec(fields) => {
|
2012-07-14 00:57:48 -05:00
|
|
|
do self.bracketed(~"rec",
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(vec::len(fields))]
|
|
|
|
+ self.c_size_and_align(t)) {
|
|
|
|
for fields.eachi |i, field| {
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"rec_field",
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(i),
|
2012-07-18 18:18:02 -05:00
|
|
|
self.c_slice(
|
|
|
|
bcx.ccx().sess.str_of(field.ident))]
|
2012-06-19 20:35:56 -05:00
|
|
|
+ self.c_mt(field.mt));
|
|
|
|
}
|
2012-06-08 15:26:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::ty_tup(tys) => {
|
2012-07-14 00:57:48 -05:00
|
|
|
do self.bracketed(~"tup",
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(vec::len(tys))]
|
|
|
|
+ self.c_size_and_align(t)) {
|
|
|
|
for tys.eachi |i, t| {
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"tup_field",
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(i),
|
2012-09-21 20:43:30 -05:00
|
|
|
self.c_tydesc(*t)]);
|
2012-06-19 20:35:56 -05:00
|
|
|
}
|
2012-06-08 15:26:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-31 19:12:29 -06:00
|
|
|
// FIXME (#2594): fetch constants out of intrinsic
|
|
|
|
// FIXME (#4809): visitor should break out bare fns from other fns
|
|
|
|
ty::ty_closure(ref fty) => {
|
|
|
|
let pureval = ast_purity_constant(fty.purity);
|
|
|
|
let sigilval = ast_sigil_constant(fty.sigil);
|
|
|
|
let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
|
|
|
|
let extra = ~[self.c_uint(pureval),
|
|
|
|
self.c_uint(sigilval),
|
|
|
|
self.c_uint(vec::len(fty.sig.inputs)),
|
|
|
|
self.c_uint(retval)];
|
|
|
|
self.visit(~"enter_fn", copy extra); // XXX: Bad copy.
|
|
|
|
self.visit_sig(retval, &fty.sig);
|
|
|
|
self.visit(~"leave_fn", extra);
|
|
|
|
}
|
|
|
|
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#2594): fetch constants out of intrinsic:: for the
|
|
|
|
// numbers.
|
2013-01-31 19:12:29 -06:00
|
|
|
ty::ty_bare_fn(ref fty) => {
|
|
|
|
let pureval = ast_purity_constant(fty.purity);
|
|
|
|
let sigilval = 0u;
|
2013-01-08 08:21:19 -06:00
|
|
|
let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
|
2012-06-29 18:26:56 -05:00
|
|
|
let extra = ~[self.c_uint(pureval),
|
2013-01-31 19:12:29 -06:00
|
|
|
self.c_uint(sigilval),
|
2012-09-07 09:37:19 -05:00
|
|
|
self.c_uint(vec::len(fty.sig.inputs)),
|
|
|
|
self.c_uint(retval)];
|
2013-01-07 16:16:52 -06:00
|
|
|
self.visit(~"enter_fn", copy extra); // XXX: Bad copy.
|
2013-01-31 19:12:29 -06:00
|
|
|
self.visit_sig(retval, &fty.sig);
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"leave_fn", extra);
|
2012-06-08 15:26:06 -05:00
|
|
|
}
|
|
|
|
|
2012-12-10 15:47:54 -06:00
|
|
|
ty::ty_struct(did, ref substs) => {
|
2012-06-08 17:35:55 -05:00
|
|
|
let bcx = self.bcx;
|
|
|
|
let tcx = bcx.ccx().tcx;
|
2012-12-10 15:47:54 -06:00
|
|
|
let fields = ty::struct_fields(tcx, did, substs);
|
2012-06-14 21:53:56 -05:00
|
|
|
|
2012-12-10 15:47:54 -06:00
|
|
|
do self.bracketed(~"class", ~[self.c_uint(fields.len())]
|
2012-06-19 20:35:56 -05:00
|
|
|
+ self.c_size_and_align(t)) {
|
|
|
|
for fields.eachi |i, field| {
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"class_field",
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(i),
|
2012-07-18 18:18:02 -05:00
|
|
|
self.c_slice(
|
|
|
|
bcx.ccx().sess.str_of(field.ident))]
|
2012-06-19 20:35:56 -05:00
|
|
|
+ self.c_mt(field.mt));
|
|
|
|
}
|
2012-06-08 17:35:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#2595): visiting all the variants in turn is probably
|
|
|
|
// not ideal. It'll work but will get costly on big enums. Maybe
|
|
|
|
// let the visitor tell us if it wants to visit only a particular
|
|
|
|
// variant?
|
2012-08-10 12:49:31 -05:00
|
|
|
ty::ty_enum(did, ref substs) => {
|
2012-06-08 17:35:55 -05:00
|
|
|
let bcx = self.bcx;
|
|
|
|
let tcx = bcx.ccx().tcx;
|
|
|
|
let variants = ty::substd_enum_variants(tcx, did, substs);
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
do self.bracketed(~"enum",
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(vec::len(variants))]
|
|
|
|
+ self.c_size_and_align(t)) {
|
|
|
|
for variants.eachi |i, v| {
|
2012-07-14 00:57:48 -05:00
|
|
|
do self.bracketed(~"enum_variant",
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(i),
|
|
|
|
self.c_int(v.disr_val),
|
|
|
|
self.c_uint(vec::len(v.args)),
|
2012-07-18 18:18:02 -05:00
|
|
|
self.c_slice(
|
|
|
|
bcx.ccx().sess.str_of(v.name))]) {
|
2012-06-19 20:35:56 -05:00
|
|
|
for v.args.eachi |j, a| {
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"enum_variant_field",
|
2012-06-19 20:35:56 -05:00
|
|
|
~[self.c_uint(j),
|
2012-09-21 20:43:30 -05:00
|
|
|
self.c_tydesc(*a)]);
|
2012-06-19 20:35:56 -05:00
|
|
|
}
|
|
|
|
}
|
2012-06-08 17:35:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-06-08 15:26:06 -05:00
|
|
|
|
|
|
|
// Miscallaneous extra types
|
2012-08-14 17:27:06 -05:00
|
|
|
ty::ty_trait(_, _, _) => self.leaf(~"trait"),
|
2012-09-06 14:30:15 -05:00
|
|
|
ty::ty_infer(_) => self.leaf(~"infer"),
|
2012-11-16 21:22:48 -06:00
|
|
|
ty::ty_err => self.leaf(~"err"),
|
2012-08-03 21:59:04 -05:00
|
|
|
ty::ty_param(p) => self.visit(~"param", ~[self.c_uint(p.idx)]),
|
|
|
|
ty::ty_self => self.leaf(~"self"),
|
|
|
|
ty::ty_type => self.leaf(~"type"),
|
|
|
|
ty::ty_opaque_box => self.leaf(~"opaque_box"),
|
|
|
|
ty::ty_opaque_closure_ptr(ck) => {
|
2013-01-31 19:12:29 -06:00
|
|
|
let ckval = ast_sigil_constant(ck);
|
2012-07-14 00:57:48 -05:00
|
|
|
self.visit(~"closure_ptr", ~[self.c_uint(ckval)])
|
2012-06-08 15:26:06 -05:00
|
|
|
}
|
2012-06-07 15:51:35 -05:00
|
|
|
}
|
2012-05-14 19:57:39 -05:00
|
|
|
}
|
2013-01-31 19:12:29 -06:00
|
|
|
|
2013-02-04 16:02:01 -06:00
|
|
|
fn visit_sig(&mut self, retval: uint, sig: &ty::FnSig) {
|
2013-01-31 19:12:29 -06:00
|
|
|
for sig.inputs.eachi |i, arg| {
|
|
|
|
let modeval = match arg.mode {
|
|
|
|
ast::infer(_) => 0u,
|
|
|
|
ast::expl(e) => match e {
|
|
|
|
ast::by_ref => 1u,
|
|
|
|
ast::by_val => 2u,
|
|
|
|
ast::by_copy => 5u
|
|
|
|
}
|
|
|
|
};
|
|
|
|
self.visit(~"fn_input",
|
|
|
|
~[self.c_uint(i),
|
|
|
|
self.c_uint(modeval),
|
|
|
|
self.c_tydesc(arg.ty)]);
|
|
|
|
}
|
|
|
|
self.visit(~"fn_output",
|
|
|
|
~[self.c_uint(retval),
|
|
|
|
self.c_tydesc(sig.output)]);
|
|
|
|
}
|
2012-05-14 19:57:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Emit a sequence of calls to visit_ty::visit_foo
|
2013-01-30 13:46:19 -06:00
|
|
|
pub fn emit_calls_to_trait_visit_ty(bcx: block,
|
|
|
|
t: ty::t,
|
|
|
|
visitor_val: ValueRef,
|
|
|
|
visitor_trait_id: def_id)
|
|
|
|
-> block {
|
2012-09-07 20:08:21 -05:00
|
|
|
use syntax::parse::token::special_idents::tydesc;
|
2012-07-14 00:57:48 -05:00
|
|
|
let final = sub_block(bcx, ~"final");
|
2013-02-02 01:04:22 -06:00
|
|
|
assert bcx.ccx().tcx.intrinsic_defs.contains_key_ref(&tydesc);
|
2013-02-05 21:41:45 -06:00
|
|
|
let (_, tydesc_ty) = bcx.ccx().tcx.intrinsic_defs.get(&tydesc);
|
2012-06-19 20:35:56 -05:00
|
|
|
let tydesc_ty = type_of::type_of(bcx.ccx(), tydesc_ty);
|
2013-02-04 16:02:01 -06:00
|
|
|
let mut r = Reflector {
|
2012-06-07 15:51:35 -05:00
|
|
|
visitor_val: visitor_val,
|
2012-08-10 17:13:24 -05:00
|
|
|
visitor_methods: ty::trait_methods(bcx.tcx(), visitor_trait_id),
|
2012-06-19 20:35:56 -05:00
|
|
|
final_bcx: final,
|
|
|
|
tydesc_ty: tydesc_ty,
|
2013-02-04 16:02:01 -06:00
|
|
|
bcx: bcx
|
|
|
|
};
|
2012-06-07 15:51:35 -05:00
|
|
|
r.visit_ty(t);
|
2012-06-19 20:35:56 -05:00
|
|
|
Br(r.bcx, final.llbb);
|
2012-08-01 19:30:05 -05:00
|
|
|
return final;
|
2012-05-14 19:57:39 -05:00
|
|
|
}
|
2012-11-04 22:41:00 -06:00
|
|
|
|
2013-01-31 19:12:29 -06:00
|
|
|
pub fn ast_sigil_constant(sigil: ast::Sigil) -> uint {
|
|
|
|
match sigil {
|
|
|
|
ast::OwnedSigil => 2u,
|
|
|
|
ast::ManagedSigil => 3u,
|
|
|
|
ast::BorrowedSigil => 4u,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ast_purity_constant(purity: ast::purity) -> uint {
|
|
|
|
match purity {
|
|
|
|
ast::pure_fn => 0u,
|
|
|
|
ast::unsafe_fn => 1u,
|
|
|
|
ast::impure_fn => 2u,
|
|
|
|
ast::extern_fn => 3u
|
2012-11-04 22:41:00 -06:00
|
|
|
}
|
2012-11-28 19:33:30 -06:00
|
|
|
}
|
2013-01-30 13:46:19 -06:00
|
|
|
|