提交 fcfbfde0 编写于 作者: J Jed Davis

Adjust reflection for the possibility of discriminants larger than int.

Not only can discriminants be smaller than int now, but they can be
larger than int on 32-bit targets.  This has obvious implications for the
reflection interface.  Without this change, things fail with LLVM
assertions when we try to "extend" i64 to i32.
上级 92109b12
......@@ -868,6 +868,10 @@ pub fn C_i64(i: i64) -> ValueRef {
return C_integral(Type::i64(), i as u64, true);
}
pub fn C_u64(i: u64) -> ValueRef {
return C_integral(Type::i64(), i, false);
}
pub fn C_int(cx: &CrateContext, i: int) -> ValueRef {
return C_integral(cx.int_type, i as u64, true);
}
......
......@@ -292,11 +292,11 @@ pub fn visit_ty(&mut self, t: ty::t) {
sub_path,
"get_disr");
let llfdecl = decl_internal_rust_fn(ccx, [opaqueptrty], ty::mk_int(), sym);
let llfdecl = decl_internal_rust_fn(ccx, [opaqueptrty], ty::mk_u64(), sym);
let fcx = new_fn_ctxt(ccx,
~[],
llfdecl,
ty::mk_uint(),
ty::mk_u64(),
None);
let arg = unsafe {
//
......@@ -308,7 +308,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
};
let mut bcx = fcx.entry_bcx.unwrap();
let arg = BitCast(bcx, arg, llptrty);
let ret = adt::trans_get_discr(bcx, repr, arg, Some(ccx.int_type));
let ret = adt::trans_get_discr(bcx, repr, arg, Some(Type::i64()));
Store(bcx, ret, fcx.llretptr.unwrap());
match fcx.llreturn {
Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn),
......@@ -324,7 +324,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
for (i, v) in variants.iter().enumerate() {
let name = ccx.sess.str_of(v.name);
let variant_args = ~[this.c_uint(i),
C_integral(self.bcx.ccx().int_type, v.disr_val, false),
C_u64(v.disr_val),
this.c_uint(v.args.len()),
this.c_slice(name)];
do this.bracketed("enum_variant", variant_args) |this| {
......
......@@ -16,7 +16,7 @@
#[allow(missing_doc)];
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor};
use libc::c_void;
use mem;
use unstable::raw;
......@@ -396,7 +396,7 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
}
fn visit_enter_enum(&mut self, n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
sz: uint, align: uint)
-> bool {
self.align(align);
......@@ -407,7 +407,7 @@ fn visit_enter_enum(&mut self, n_variants: uint,
}
fn visit_enter_enum_variant(&mut self, variant: uint,
disr_val: int,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool {
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
......@@ -426,7 +426,7 @@ fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) ->
}
fn visit_leave_enum_variant(&mut self, variant: uint,
disr_val: int,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool {
if ! self.inner.visit_leave_enum_variant(variant, disr_val,
......@@ -437,7 +437,7 @@ fn visit_leave_enum_variant(&mut self, variant: uint,
}
fn visit_leave_enum(&mut self, n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
sz: uint, align: uint) -> bool {
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
return false;
......
......@@ -29,7 +29,7 @@
use str::StrSlice;
use to_str::ToStr;
use vec::OwnedVector;
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
use unstable::raw;
/// Representations
......@@ -92,7 +92,7 @@ fn write_repr(&self, writer: &mut io::Writer) {
// New implementation using reflect::MovePtr
enum VariantState {
SearchingFor(int),
SearchingFor(Disr),
Matched,
AlreadyFound
}
......@@ -473,7 +473,7 @@ fn visit_leave_tup(&mut self, _n_fields: uint,
fn visit_enter_enum(&mut self,
_n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
_sz: uint,
_align: uint) -> bool {
let disr = unsafe {
......@@ -484,7 +484,7 @@ fn visit_enter_enum(&mut self,
}
fn visit_enter_enum_variant(&mut self, _variant: uint,
disr_val: int,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool {
let mut write = false;
......@@ -531,7 +531,7 @@ fn visit_enum_variant_field(&mut self,
}
fn visit_leave_enum_variant(&mut self, _variant: uint,
_disr_val: int,
_disr_val: Disr,
n_fields: uint,
_name: &str) -> bool {
match self.var_stk[self.var_stk.len() - 1] {
......@@ -547,7 +547,7 @@ fn visit_leave_enum_variant(&mut self, _variant: uint,
fn visit_leave_enum(&mut self,
_n_variants: uint,
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
_get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
_sz: uint,
_align: uint)
-> bool {
......
......@@ -75,6 +75,11 @@ pub struct TyDesc {
#[cfg(not(test))]
pub enum Opaque { }
#[cfg(stage0)]
pub type Disr = int;
#[cfg(not(stage0))]
pub type Disr = u64;
#[lang="ty_visitor"]
#[cfg(not(test))]
pub trait TyVisitor {
......@@ -140,19 +145,19 @@ fn visit_leave_tup(&mut self, n_fields: uint,
sz: uint, align: uint) -> bool;
fn visit_enter_enum(&mut self, n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
sz: uint, align: uint) -> bool;
fn visit_enter_enum_variant(&mut self, variant: uint,
disr_val: int,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool;
fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool;
fn visit_leave_enum_variant(&mut self, variant: uint,
disr_val: int,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool;
fn visit_leave_enum(&mut self, n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
sz: uint, align: uint) -> bool;
fn visit_enter_fn(&mut self, purity: uint, proto: uint,
......
......@@ -13,13 +13,8 @@
pub fn main() {
enum E { V = 0x1717171717171717 }
static C: E = V;
let expected: u64 = if mem::size_of::<uint>() < 8 {
0x17171717
} else {
0x1717171717171717
};
assert_eq!(expected, V as u64);
assert_eq!(expected, C as u64);
assert_eq!(V as u64, 0x1717171717171717u64);
assert_eq!(C as u64, 0x1717171717171717u64);
assert_eq!(format!("{:?}", V), ~"V");
assert_eq!(format!("{:?}", C), ~"V");
}
......@@ -15,7 +15,7 @@
use std::libc::c_void;
use std::ptr;
use std::mem;
use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Disr, Opaque};
use std::unstable::raw::Vec;
#[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."]
......@@ -380,7 +380,7 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
}
fn visit_enter_enum(&mut self, n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
sz: uint, align: uint)
-> bool {
self.align(align);
......@@ -389,7 +389,7 @@ fn visit_enter_enum(&mut self, n_variants: uint,
}
fn visit_enter_enum_variant(&mut self, variant: uint,
disr_val: int,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool {
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
......@@ -405,7 +405,7 @@ fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) ->
}
fn visit_leave_enum_variant(&mut self, variant: uint,
disr_val: int,
disr_val: Disr,
n_fields: uint,
name: &str) -> bool {
if ! self.inner.visit_leave_enum_variant(variant, disr_val,
......@@ -416,7 +416,7 @@ fn visit_leave_enum_variant(&mut self, variant: uint,
}
fn visit_leave_enum(&mut self, n_variants: uint,
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
sz: uint, align: uint)
-> bool {
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) { return false; }
......@@ -578,24 +578,24 @@ fn visit_leave_tup(&mut self, _n_fields: uint,
_sz: uint, _align: uint) -> bool { true }
fn visit_enter_enum(&mut self, _n_variants: uint,
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
_get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
_sz: uint, _align: uint) -> bool {
// FIXME (#3732): this needs to rewind between enum variants, or something.
true
}
fn visit_enter_enum_variant(&mut self, _variant: uint,
_disr_val: int,
_disr_val: Disr,
_n_fields: uint,
_name: &str) -> bool { true }
fn visit_enum_variant_field(&mut self, _i: uint, _offset: uint, inner: *TyDesc) -> bool {
self.visit_inner(inner)
}
fn visit_leave_enum_variant(&mut self, _variant: uint,
_disr_val: int,
_disr_val: Disr,
_n_fields: uint,
_name: &str) -> bool { true }
fn visit_leave_enum(&mut self, _n_variants: uint,
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
_get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
_sz: uint, _align: uint) -> bool { true }
fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
......
......@@ -10,7 +10,7 @@
#[feature(managed_boxes)];
use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Disr, Opaque};
struct MyVisitor {
types: @mut ~[~str],
......@@ -114,22 +114,22 @@ fn visit_leave_tup(&mut self, _n_fields: uint,
_sz: uint, _align: uint) -> bool { true }
fn visit_enter_enum(&mut self, _n_variants: uint,
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
_get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
_sz: uint, _align: uint) -> bool { true }
fn visit_enter_enum_variant(&mut self,
_variant: uint,
_disr_val: int,
_disr_val: Disr,
_n_fields: uint,
_name: &str) -> bool { true }
fn visit_enum_variant_field(&mut self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true }
fn visit_leave_enum_variant(&mut self,
_variant: uint,
_disr_val: int,
_disr_val: Disr,
_n_fields: uint,
_name: &str) -> bool { true }
fn visit_leave_enum(&mut self,
_n_variants: uint,
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
_get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
_sz: uint, _align: uint) -> bool { true }
fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册