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.
This commit is contained in:
parent
92109b1202
commit
fcfbfde0b7
8 changed files with 44 additions and 40 deletions
|
@ -868,6 +868,10 @@ pub fn C_i64(i: i64) -> ValueRef {
|
||||||
return C_integral(Type::i64(), i as u64, true);
|
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 {
|
pub fn C_int(cx: &CrateContext, i: int) -> ValueRef {
|
||||||
return C_integral(cx.int_type, i as u64, true);
|
return C_integral(cx.int_type, i as u64, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,11 +292,11 @@ impl Reflector {
|
||||||
sub_path,
|
sub_path,
|
||||||
"get_disr");
|
"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,
|
let fcx = new_fn_ctxt(ccx,
|
||||||
~[],
|
~[],
|
||||||
llfdecl,
|
llfdecl,
|
||||||
ty::mk_uint(),
|
ty::mk_u64(),
|
||||||
None);
|
None);
|
||||||
let arg = unsafe {
|
let arg = unsafe {
|
||||||
//
|
//
|
||||||
|
@ -308,7 +308,7 @@ impl Reflector {
|
||||||
};
|
};
|
||||||
let mut bcx = fcx.entry_bcx.unwrap();
|
let mut bcx = fcx.entry_bcx.unwrap();
|
||||||
let arg = BitCast(bcx, arg, llptrty);
|
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());
|
Store(bcx, ret, fcx.llretptr.unwrap());
|
||||||
match fcx.llreturn {
|
match fcx.llreturn {
|
||||||
Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn),
|
Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn),
|
||||||
|
@ -324,7 +324,7 @@ impl Reflector {
|
||||||
for (i, v) in variants.iter().enumerate() {
|
for (i, v) in variants.iter().enumerate() {
|
||||||
let name = ccx.sess.str_of(v.name);
|
let name = ccx.sess.str_of(v.name);
|
||||||
let variant_args = ~[this.c_uint(i),
|
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_uint(v.args.len()),
|
||||||
this.c_slice(name)];
|
this.c_slice(name)];
|
||||||
do this.bracketed("enum_variant", variant_args) |this| {
|
do this.bracketed("enum_variant", variant_args) |this| {
|
||||||
|
|
|
@ -16,7 +16,7 @@ Runtime type reflection
|
||||||
|
|
||||||
#[allow(missing_doc)];
|
#[allow(missing_doc)];
|
||||||
|
|
||||||
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
|
use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor};
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use mem;
|
use mem;
|
||||||
use unstable::raw;
|
use unstable::raw;
|
||||||
|
@ -396,7 +396,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_enter_enum(&mut self, n_variants: 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)
|
sz: uint, align: uint)
|
||||||
-> bool {
|
-> bool {
|
||||||
self.align(align);
|
self.align(align);
|
||||||
|
@ -407,7 +407,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_enter_enum_variant(&mut self, variant: uint,
|
fn visit_enter_enum_variant(&mut self, variant: uint,
|
||||||
disr_val: int,
|
disr_val: Disr,
|
||||||
n_fields: uint,
|
n_fields: uint,
|
||||||
name: &str) -> bool {
|
name: &str) -> bool {
|
||||||
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
|
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
|
||||||
|
@ -426,7 +426,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_leave_enum_variant(&mut self, variant: uint,
|
fn visit_leave_enum_variant(&mut self, variant: uint,
|
||||||
disr_val: int,
|
disr_val: Disr,
|
||||||
n_fields: uint,
|
n_fields: uint,
|
||||||
name: &str) -> bool {
|
name: &str) -> bool {
|
||||||
if ! self.inner.visit_leave_enum_variant(variant, disr_val,
|
if ! self.inner.visit_leave_enum_variant(variant, disr_val,
|
||||||
|
@ -437,7 +437,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_leave_enum(&mut self, n_variants: 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 {
|
sz: uint, align: uint) -> bool {
|
||||||
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
|
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,7 +29,7 @@ use reflect::{MovePtr, align};
|
||||||
use str::StrSlice;
|
use str::StrSlice;
|
||||||
use to_str::ToStr;
|
use to_str::ToStr;
|
||||||
use vec::OwnedVector;
|
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;
|
use unstable::raw;
|
||||||
|
|
||||||
/// Representations
|
/// Representations
|
||||||
|
@ -92,7 +92,7 @@ num_repr!(f64, "f64")
|
||||||
// New implementation using reflect::MovePtr
|
// New implementation using reflect::MovePtr
|
||||||
|
|
||||||
enum VariantState {
|
enum VariantState {
|
||||||
SearchingFor(int),
|
SearchingFor(Disr),
|
||||||
Matched,
|
Matched,
|
||||||
AlreadyFound
|
AlreadyFound
|
||||||
}
|
}
|
||||||
|
@ -473,7 +473,7 @@ impl<'self> TyVisitor for ReprVisitor<'self> {
|
||||||
|
|
||||||
fn visit_enter_enum(&mut self,
|
fn visit_enter_enum(&mut self,
|
||||||
_n_variants: uint,
|
_n_variants: uint,
|
||||||
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
|
get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
|
||||||
_sz: uint,
|
_sz: uint,
|
||||||
_align: uint) -> bool {
|
_align: uint) -> bool {
|
||||||
let disr = unsafe {
|
let disr = unsafe {
|
||||||
|
@ -484,7 +484,7 @@ impl<'self> TyVisitor for ReprVisitor<'self> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_enter_enum_variant(&mut self, _variant: uint,
|
fn visit_enter_enum_variant(&mut self, _variant: uint,
|
||||||
disr_val: int,
|
disr_val: Disr,
|
||||||
n_fields: uint,
|
n_fields: uint,
|
||||||
name: &str) -> bool {
|
name: &str) -> bool {
|
||||||
let mut write = false;
|
let mut write = false;
|
||||||
|
@ -531,7 +531,7 @@ impl<'self> TyVisitor for ReprVisitor<'self> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_leave_enum_variant(&mut self, _variant: uint,
|
fn visit_leave_enum_variant(&mut self, _variant: uint,
|
||||||
_disr_val: int,
|
_disr_val: Disr,
|
||||||
n_fields: uint,
|
n_fields: uint,
|
||||||
_name: &str) -> bool {
|
_name: &str) -> bool {
|
||||||
match self.var_stk[self.var_stk.len() - 1] {
|
match self.var_stk[self.var_stk.len() - 1] {
|
||||||
|
@ -547,7 +547,7 @@ impl<'self> TyVisitor for ReprVisitor<'self> {
|
||||||
|
|
||||||
fn visit_leave_enum(&mut self,
|
fn visit_leave_enum(&mut self,
|
||||||
_n_variants: uint,
|
_n_variants: uint,
|
||||||
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
|
_get_disr: extern unsafe fn(ptr: *Opaque) -> Disr,
|
||||||
_sz: uint,
|
_sz: uint,
|
||||||
_align: uint)
|
_align: uint)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
|
|
@ -75,6 +75,11 @@ pub struct TyDesc {
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
pub enum Opaque { }
|
pub enum Opaque { }
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
|
pub type Disr = int;
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
pub type Disr = u64;
|
||||||
|
|
||||||
#[lang="ty_visitor"]
|
#[lang="ty_visitor"]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
pub trait TyVisitor {
|
pub trait TyVisitor {
|
||||||
|
@ -140,19 +145,19 @@ pub trait TyVisitor {
|
||||||
sz: uint, align: uint) -> bool;
|
sz: uint, align: uint) -> bool;
|
||||||
|
|
||||||
fn visit_enter_enum(&mut self, n_variants: 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;
|
sz: uint, align: uint) -> bool;
|
||||||
fn visit_enter_enum_variant(&mut self, variant: uint,
|
fn visit_enter_enum_variant(&mut self, variant: uint,
|
||||||
disr_val: int,
|
disr_val: Disr,
|
||||||
n_fields: uint,
|
n_fields: uint,
|
||||||
name: &str) -> bool;
|
name: &str) -> bool;
|
||||||
fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool;
|
fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool;
|
||||||
fn visit_leave_enum_variant(&mut self, variant: uint,
|
fn visit_leave_enum_variant(&mut self, variant: uint,
|
||||||
disr_val: int,
|
disr_val: Disr,
|
||||||
n_fields: uint,
|
n_fields: uint,
|
||||||
name: &str) -> bool;
|
name: &str) -> bool;
|
||||||
fn visit_leave_enum(&mut self, n_variants: 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;
|
sz: uint, align: uint) -> bool;
|
||||||
|
|
||||||
fn visit_enter_fn(&mut self, purity: uint, proto: uint,
|
fn visit_enter_fn(&mut self, purity: uint, proto: uint,
|
||||||
|
|
|
@ -13,13 +13,8 @@ use std::mem;
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
enum E { V = 0x1717171717171717 }
|
enum E { V = 0x1717171717171717 }
|
||||||
static C: E = V;
|
static C: E = V;
|
||||||
let expected: u64 = if mem::size_of::<uint>() < 8 {
|
assert_eq!(V as u64, 0x1717171717171717u64);
|
||||||
0x17171717
|
assert_eq!(C as u64, 0x1717171717171717u64);
|
||||||
} else {
|
|
||||||
0x1717171717171717
|
|
||||||
};
|
|
||||||
assert_eq!(expected, V as u64);
|
|
||||||
assert_eq!(expected, C as u64);
|
|
||||||
assert_eq!(format!("{:?}", V), ~"V");
|
assert_eq!(format!("{:?}", V), ~"V");
|
||||||
assert_eq!(format!("{:?}", C), ~"V");
|
assert_eq!(format!("{:?}", C), ~"V");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
use std::libc::c_void;
|
use std::libc::c_void;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::mem;
|
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;
|
use std::unstable::raw::Vec;
|
||||||
|
|
||||||
#[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."]
|
#[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."]
|
||||||
|
@ -380,7 +380,7 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_enter_enum(&mut self, n_variants: 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)
|
sz: uint, align: uint)
|
||||||
-> bool {
|
-> bool {
|
||||||
self.align(align);
|
self.align(align);
|
||||||
|
@ -389,7 +389,7 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_enter_enum_variant(&mut self, variant: uint,
|
fn visit_enter_enum_variant(&mut self, variant: uint,
|
||||||
disr_val: int,
|
disr_val: Disr,
|
||||||
n_fields: uint,
|
n_fields: uint,
|
||||||
name: &str) -> bool {
|
name: &str) -> bool {
|
||||||
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
|
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
|
||||||
|
@ -405,7 +405,7 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_leave_enum_variant(&mut self, variant: uint,
|
fn visit_leave_enum_variant(&mut self, variant: uint,
|
||||||
disr_val: int,
|
disr_val: Disr,
|
||||||
n_fields: uint,
|
n_fields: uint,
|
||||||
name: &str) -> bool {
|
name: &str) -> bool {
|
||||||
if ! self.inner.visit_leave_enum_variant(variant, disr_val,
|
if ! self.inner.visit_leave_enum_variant(variant, disr_val,
|
||||||
|
@ -416,7 +416,7 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_leave_enum(&mut self, n_variants: 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)
|
sz: uint, align: uint)
|
||||||
-> bool {
|
-> bool {
|
||||||
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) { return false; }
|
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) { return false; }
|
||||||
|
@ -578,24 +578,24 @@ impl TyVisitor for my_visitor {
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_enum(&mut self, _n_variants: 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 {
|
_sz: uint, _align: uint) -> bool {
|
||||||
// FIXME (#3732): this needs to rewind between enum variants, or something.
|
// FIXME (#3732): this needs to rewind between enum variants, or something.
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
fn visit_enter_enum_variant(&mut self, _variant: uint,
|
fn visit_enter_enum_variant(&mut self, _variant: uint,
|
||||||
_disr_val: int,
|
_disr_val: Disr,
|
||||||
_n_fields: uint,
|
_n_fields: uint,
|
||||||
_name: &str) -> bool { true }
|
_name: &str) -> bool { true }
|
||||||
fn visit_enum_variant_field(&mut self, _i: uint, _offset: uint, inner: *TyDesc) -> bool {
|
fn visit_enum_variant_field(&mut self, _i: uint, _offset: uint, inner: *TyDesc) -> bool {
|
||||||
self.visit_inner(inner)
|
self.visit_inner(inner)
|
||||||
}
|
}
|
||||||
fn visit_leave_enum_variant(&mut self, _variant: uint,
|
fn visit_leave_enum_variant(&mut self, _variant: uint,
|
||||||
_disr_val: int,
|
_disr_val: Disr,
|
||||||
_n_fields: uint,
|
_n_fields: uint,
|
||||||
_name: &str) -> bool { true }
|
_name: &str) -> bool { true }
|
||||||
fn visit_leave_enum(&mut self, _n_variants: 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 { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
|
fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#[feature(managed_boxes)];
|
#[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 {
|
struct MyVisitor {
|
||||||
types: @mut ~[~str],
|
types: @mut ~[~str],
|
||||||
|
@ -114,22 +114,22 @@ impl TyVisitor for MyVisitor {
|
||||||
_sz: uint, _align: uint) -> bool { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_enum(&mut self, _n_variants: 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 { true }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
fn visit_enter_enum_variant(&mut self,
|
fn visit_enter_enum_variant(&mut self,
|
||||||
_variant: uint,
|
_variant: uint,
|
||||||
_disr_val: int,
|
_disr_val: Disr,
|
||||||
_n_fields: uint,
|
_n_fields: uint,
|
||||||
_name: &str) -> bool { true }
|
_name: &str) -> bool { true }
|
||||||
fn visit_enum_variant_field(&mut self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true }
|
fn visit_enum_variant_field(&mut self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true }
|
||||||
fn visit_leave_enum_variant(&mut self,
|
fn visit_leave_enum_variant(&mut self,
|
||||||
_variant: uint,
|
_variant: uint,
|
||||||
_disr_val: int,
|
_disr_val: Disr,
|
||||||
_n_fields: uint,
|
_n_fields: uint,
|
||||||
_name: &str) -> bool { true }
|
_name: &str) -> bool { true }
|
||||||
fn visit_leave_enum(&mut self,
|
fn visit_leave_enum(&mut self,
|
||||||
_n_variants: uint,
|
_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 }
|
_sz: uint, _align: uint) -> bool { true }
|
||||||
|
|
||||||
fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
|
fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
|
||||||
|
|
Loading…
Reference in a new issue