Skip to content

Commit 2dfb6f2

Browse files
committed
---
yaml --- r: 55530 b: refs/heads/master c: 3809a04 h: refs/heads/master v: v3
1 parent 6b94cbb commit 2dfb6f2

File tree

6 files changed

+202
-29
lines changed

6 files changed

+202
-29
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 7b152baddfec6c4c475cb51b8428108c8c41af27
2+
refs/heads/master: 3809a04bf79fe75ff48fd7aa48f7858472ee37f5
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 79a2b2eafc3c766cecec8a5f76317693bae9ed17
55
refs/heads/try: 8eb2bab100b42f0ba751552d8eff00eb2134c55a

trunk/src/libcore/reflect.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Runtime type reflection
1515
*/
1616

1717
use intrinsic::{TyDesc, TyVisitor};
18+
#[cfg(not(stage0))] use intrinsic::Opaque;
1819
use libc::c_void;
1920
use sys;
2021
use vec;
@@ -393,6 +394,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
393394
true
394395
}
395396

397+
#[cfg(stage0)]
396398
fn visit_enter_enum(&self, n_variants: uint, sz: uint, align: uint)
397399
-> bool {
398400
self.align(align);
@@ -402,25 +404,47 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
402404
true
403405
}
404406

407+
#[cfg(not(stage0))]
408+
fn visit_enter_enum(&self, n_variants: uint,
409+
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
410+
sz: uint, align: uint)
411+
-> bool {
412+
self.align(align);
413+
if ! self.inner.visit_enter_enum(n_variants, get_disr, sz, align) {
414+
return false;
415+
}
416+
true
417+
}
418+
405419
fn visit_enter_enum_variant(&self, variant: uint,
406420
disr_val: int,
407421
n_fields: uint,
408422
name: &str) -> bool {
409-
self.inner.push_ptr();
423+
self.inner.push_ptr(); // NOTE remove after next snapshot
410424
if ! self.inner.visit_enter_enum_variant(variant, disr_val,
411425
n_fields, name) {
412426
return false;
413427
}
414428
true
415429
}
416430

431+
#[cfg(stage0)]
417432
fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
418433
unsafe { self.align((*inner).align); }
419434
if ! self.inner.visit_enum_variant_field(i, inner) { return false; }
420435
unsafe { self.bump((*inner).size); }
421436
true
422437
}
423438

439+
#[cfg(not(stage0))]
440+
fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool {
441+
self.inner.push_ptr();
442+
self.bump(offset);
443+
if ! self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
444+
self.inner.pop_ptr();
445+
true
446+
}
447+
424448
fn visit_leave_enum_variant(&self, variant: uint,
425449
disr_val: int,
426450
n_fields: uint,
@@ -429,10 +453,11 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
429453
n_fields, name) {
430454
return false;
431455
}
432-
self.inner.pop_ptr();
456+
self.inner.pop_ptr(); // NOTE remove after next snapshot
433457
true
434458
}
435459

460+
#[cfg(stage0)]
436461
fn visit_leave_enum(&self, n_variants: uint, sz: uint, align: uint)
437462
-> bool {
438463
if ! self.inner.visit_leave_enum(n_variants, sz, align) {
@@ -442,6 +467,17 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
442467
true
443468
}
444469

470+
#[cfg(not(stage0))]
471+
fn visit_leave_enum(&self, n_variants: uint,
472+
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
473+
sz: uint, align: uint) -> bool {
474+
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
475+
return false;
476+
}
477+
self.bump(sz);
478+
true
479+
}
480+
445481
fn visit_trait(&self) -> bool {
446482
self.align_to::<@TyVisitor>();
447483
if ! self.inner.visit_trait() { return false; }

trunk/src/libcore/repr.rs

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use cast::transmute;
1818
use char;
1919
use intrinsic;
2020
use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
21+
#[cfg(not(stage0))] use intrinsic::Opaque;
2122
use io::{Writer, WriterUtil};
2223
use libc::c_void;
2324
use managed;
@@ -137,12 +138,20 @@ impl Repr for char {
137138

138139
// New implementation using reflect::MovePtr
139140

141+
#[cfg(stage0)]
140142
enum VariantState {
141143
Degenerate,
142144
TagMatch,
143145
TagMismatch,
144146
}
145147

148+
#[cfg(not(stage0))]
149+
enum VariantState {
150+
SearchingFor(int),
151+
Matched,
152+
AlreadyFound
153+
}
154+
146155
pub struct ReprVisitor {
147156
mut ptr: *c_void,
148157
mut ptr_stk: ~[*c_void],
@@ -181,14 +190,14 @@ pub impl ReprVisitor {
181190
true
182191
}
183192

184-
#[inline(always)]
193+
#[cfg(stage0)] #[inline(always)]
185194
fn bump(&self, sz: uint) {
186195
do self.move_ptr() |p| {
187196
((p as uint) + sz) as *c_void
188197
};
189198
}
190199

191-
#[inline(always)]
200+
#[cfg(stage0)] #[inline(always)]
192201
fn bump_past<T>(&self) {
193202
self.bump(sys::size_of::<T>());
194203
}
@@ -458,6 +467,7 @@ impl TyVisitor for ReprVisitor {
458467
true
459468
}
460469

470+
#[cfg(stage0)]
461471
fn visit_enter_enum(&self, n_variants: uint,
462472
_sz: uint, _align: uint) -> bool {
463473
if n_variants == 1 {
@@ -468,6 +478,16 @@ impl TyVisitor for ReprVisitor {
468478
true
469479
}
470480

481+
#[cfg(not(stage0))]
482+
fn visit_enter_enum(&self, n_variants: uint,
483+
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
484+
_sz: uint, _align: uint) -> bool {
485+
let disr = unsafe { get_disr(transmute(self.ptr)) };
486+
self.var_stk.push(SearchingFor(disr));
487+
true
488+
}
489+
490+
#[cfg(stage0)]
471491
fn visit_enter_enum_variant(&self, _variant: uint,
472492
disr_val: int,
473493
n_fields: uint,
@@ -500,6 +520,36 @@ impl TyVisitor for ReprVisitor {
500520
true
501521
}
502522

523+
#[cfg(not(stage0))]
524+
fn visit_enter_enum_variant(&self, _variant: uint,
525+
disr_val: int,
526+
n_fields: uint,
527+
name: &str) -> bool {
528+
let mut write = false;
529+
match self.var_stk.pop() {
530+
SearchingFor(sought) => {
531+
if disr_val == sought {
532+
self.var_stk.push(Matched);
533+
write = true;
534+
} else {
535+
self.var_stk.push(SearchingFor(sought));
536+
}
537+
}
538+
Matched | AlreadyFound => {
539+
self.var_stk.push(AlreadyFound);
540+
}
541+
}
542+
543+
if write {
544+
self.writer.write_str(name);
545+
if n_fields > 0 {
546+
self.writer.write_char('(');
547+
}
548+
}
549+
true
550+
}
551+
552+
#[cfg(stage0)]
503553
fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
504554
match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
505555
Degenerate | TagMatch => {
@@ -515,6 +565,23 @@ impl TyVisitor for ReprVisitor {
515565
true
516566
}
517567

568+
#[cfg(not(stage0))]
569+
fn visit_enum_variant_field(&self, i: uint, _offset: uint, inner: *TyDesc) -> bool {
570+
match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
571+
Matched => {
572+
if i != 0 {
573+
self.writer.write_str(", ");
574+
}
575+
if ! self.visit_inner(inner) {
576+
return false;
577+
}
578+
}
579+
_ => ()
580+
}
581+
true
582+
}
583+
584+
#[cfg(stage0)]
518585
fn visit_leave_enum_variant(&self, _variant: uint,
519586
_disr_val: int,
520587
n_fields: uint,
@@ -530,12 +597,39 @@ impl TyVisitor for ReprVisitor {
530597
true
531598
}
532599

600+
#[cfg(not(stage0))]
601+
fn visit_leave_enum_variant(&self, _variant: uint,
602+
_disr_val: int,
603+
n_fields: uint,
604+
_name: &str) -> bool {
605+
match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
606+
Matched => {
607+
if n_fields > 0 {
608+
self.writer.write_char(')');
609+
}
610+
}
611+
_ => ()
612+
}
613+
true
614+
}
615+
616+
#[cfg(stage0)]
533617
fn visit_leave_enum(&self, _n_variants: uint,
534618
_sz: uint, _align: uint) -> bool {
535619
self.var_stk.pop();
536620
true
537621
}
538622

623+
#[cfg(not(stage0))]
624+
fn visit_leave_enum(&self, _n_variants: uint,
625+
_get_disr: extern unsafe fn(ptr: *Opaque) -> int,
626+
_sz: uint, _align: uint) -> bool {
627+
match self.var_stk.pop() {
628+
SearchingFor(*) => fail!(~"enum value matched no variant"),
629+
_ => true
630+
}
631+
}
632+
539633
fn visit_enter_fn(&self, _purity: uint, _proto: uint,
540634
_n_inputs: uint, _retstyle: uint) -> bool { true }
541635
fn visit_fn_input(&self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool {

trunk/src/librustc/front/intrinsic.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ pub mod intrinsic {
2828
// Remaining fields not listed
2929
}
3030

31+
pub enum Opaque { }
32+
3133
pub trait TyVisitor {
3234
fn visit_bot(&self) -> bool;
3335
fn visit_nil(&self) -> bool;
@@ -91,17 +93,19 @@ pub mod intrinsic {
9193
sz: uint, align: uint) -> bool;
9294

9395
fn visit_enter_enum(&self, n_variants: uint,
96+
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
9497
sz: uint, align: uint) -> bool;
9598
fn visit_enter_enum_variant(&self, variant: uint,
9699
disr_val: int,
97100
n_fields: uint,
98101
name: &str) -> bool;
99-
fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool;
102+
fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool;
100103
fn visit_leave_enum_variant(&self, variant: uint,
101104
disr_val: int,
102105
n_fields: uint,
103106
name: &str) -> bool;
104107
fn visit_leave_enum(&self, n_variants: uint,
108+
get_disr: extern unsafe fn(ptr: *Opaque) -> int,
105109
sz: uint, align: uint) -> bool;
106110

107111
fn visit_enter_fn(&self, purity: uint, proto: uint,

trunk/src/librustc/middle/trans/reflect.rs

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
12-
use lib::llvm::{TypeRef, ValueRef};
11+
use back::link::mangle_internal_name_by_path_and_seq;
12+
use lib::llvm::{TypeRef, ValueRef, llvm};
13+
use middle::trans::adt;
1314
use middle::trans::base::*;
1415
use middle::trans::build::*;
1516
use middle::trans::callee::{ArgVals, DontAutorefArg};
@@ -24,10 +25,13 @@ use middle::trans::type_of::*;
2425
use middle::ty;
2526
use util::ppaux::ty_to_str;
2627

28+
use core::libc::c_uint;
2729
use core::option::None;
2830
use core::vec;
2931
use syntax::ast::def_id;
3032
use syntax::ast;
33+
use syntax::ast_map::path_name;
34+
use syntax::parse::token::special_idents;
3135

3236
pub struct Reflector {
3337
visitor_val: ValueRef,
@@ -266,23 +270,52 @@ pub impl Reflector {
266270
// variant?
267271
ty::ty_enum(did, ref substs) => {
268272
let bcx = self.bcx;
269-
let tcx = bcx.ccx().tcx;
270-
let variants = ty::substd_enum_variants(tcx, did, substs);
273+
let ccx = bcx.ccx();
274+
let repr = adt::represent_type(bcx.ccx(), t);
275+
let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
276+
let llptrty = T_ptr(type_of(ccx, t));
277+
let (_, opaquety) = *(ccx.tcx.intrinsic_defs.find(&ccx.sess.ident_of(~"Opaque"))
278+
.expect("Failed to resolve intrinsic::Opaque"));
279+
let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm });
280+
281+
let make_get_disr = || {
282+
let sub_path = bcx.fcx.path + ~[path_name(special_idents::anon)];
283+
let sym = mangle_internal_name_by_path_and_seq(ccx, sub_path, ~"get_disr");
284+
let args = [ty::arg { mode: ast::expl(ast::by_copy),
285+
ty: opaqueptrty }];
286+
let llfty = type_of_fn(ccx, args, ty::mk_int(ccx.tcx));
287+
let llfdecl = decl_internal_cdecl_fn(ccx.llmod, sym, llfty);
288+
let arg = unsafe {
289+
llvm::LLVMGetParam(llfdecl, first_real_arg as c_uint)
290+
};
291+
let fcx = new_fn_ctxt(ccx, ~[], llfdecl, None);
292+
let bcx = top_scope_block(fcx, None);
293+
let arg = BitCast(bcx, arg, llptrty);
294+
let ret = adt::trans_get_discr(bcx, repr, arg);
295+
Store(bcx, ret, fcx.llretptr);
296+
cleanup_and_Br(bcx, bcx, fcx.llreturn);
297+
finish_fn(fcx, bcx.llbb);
298+
llfdecl
299+
};
271300

272-
let extra = ~[self.c_uint(vec::len(variants))]
301+
let enum_args = ~[self.c_uint(vec::len(variants)), make_get_disr()]
273302
+ self.c_size_and_align(t);
274-
do self.bracketed(~"enum", extra) |this| {
303+
do self.bracketed(~"enum", enum_args) |this| {
275304
for variants.eachi |i, v| {
276-
let extra1 = ~[this.c_uint(i),
277-
this.c_int(v.disr_val),
278-
this.c_uint(vec::len(v.args)),
279-
this.c_slice(
280-
bcx.ccx().sess.str_of(v.name))];
281-
do this.bracketed(~"enum_variant", extra1) |this| {
305+
let variant_args = ~[this.c_uint(i),
306+
this.c_int(v.disr_val),
307+
this.c_uint(vec::len(v.args)),
308+
this.c_slice(ccx.sess.str_of(v.name))];
309+
do this.bracketed(~"enum_variant", variant_args) |this| {
282310
for v.args.eachi |j, a| {
283-
let extra = ~[this.c_uint(j),
284-
this.c_tydesc(*a)];
285-
this.visit(~"enum_variant_field", extra);
311+
let bcx = this.bcx;
312+
let null = C_null(llptrty);
313+
let offset = p2i(ccx, adt::trans_field_ptr(bcx, repr, null,
314+
v.disr_val, j));
315+
let field_args = ~[this.c_uint(j),
316+
offset,
317+
this.c_tydesc(*a)];
318+
this.visit(~"enum_variant_field", field_args);
286319
}
287320
}
288321
}

0 commit comments

Comments
 (0)