mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-02 00:07:42 +03:00
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:
@@ -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;
|
||||
|
||||
+6
-6
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user