@@ -10,67 +10,116 @@ import type_of::*;
10
10
import ast:: def_id;
11
11
import util:: ppaux:: ty_to_str;
12
12
13
- fn visit_ty_steps ( bcx : block , t : ty :: t ,
14
- step : fn ( bcx : block ,
15
- tyname : str ,
16
- args : [ ValueRef ] ) -> block ,
17
- sub : fn ( bcx : block , t : ty :: t ) -> block ) -> block {
13
+ enum reflector = {
14
+ visitor_val : ValueRef ,
15
+ visitor_methods : @ [ ty :: method ] ,
16
+ mut bcx : block
17
+ } ;
18
18
19
- let ccx = bcx . ccx ( ) ;
19
+ impl methods for reflector {
20
20
21
- alt ty:: get ( t) . struct {
22
- ty:: ty_bot { step( bcx, "visit_bot" , [ ] ) }
23
- ty:: ty_nil { step( bcx, "visit_nil" , [ ] ) }
24
- ty:: ty_bool { step( bcx, "visit_bool" , [ ] ) }
25
- ty:: ty_int ( ast:: ty_i) { step ( bcx, "visit_int" , [ ] ) }
26
- ty:: ty_int ( ast:: ty_char) { step ( bcx, "visit_char" , [ ] ) }
27
- ty:: ty_int ( ast:: ty_i8) { step ( bcx, "visit_i8" , [ ] ) }
28
- ty:: ty_int ( ast:: ty_i16) { step ( bcx, "visit_i16" , [ ] ) }
29
- ty:: ty_int ( ast:: ty_i32) { step ( bcx, "visit_i32" , [ ] ) }
30
- ty:: ty_int ( ast:: ty_i64) { step ( bcx, "visit_i64" , [ ] ) }
31
- ty:: ty_uint ( ast:: ty_u) { step ( bcx, "visit_uint" , [ ] ) }
32
- ty:: ty_uint ( ast:: ty_u8) { step ( bcx, "visit_u8" , [ ] ) }
33
- ty:: ty_uint ( ast:: ty_u16) { step ( bcx, "visit_u16" , [ ] ) }
34
- ty:: ty_uint ( ast:: ty_u32) { step ( bcx, "visit_u32" , [ ] ) }
35
- ty:: ty_uint ( ast:: ty_u64) { step ( bcx, "visit_u64" , [ ] ) }
36
- ty:: ty_float ( ast:: ty_f) { step ( bcx, "visit_float" , [ ] ) }
37
- ty:: ty_float ( ast:: ty_f32) { step ( bcx, "visit_f32" , [ ] ) }
38
- ty:: ty_float ( ast:: ty_f64) { step ( bcx, "visit_f64" , [ ] ) }
39
- ty:: ty_str { step( bcx, "visit_str" , [ ] ) }
21
+ fn c_uint ( u : uint ) -> ValueRef {
22
+ C_uint ( self . bcx . ccx ( ) , u)
23
+ }
24
+
25
+ fn visit ( ty_name : str , args : [ ValueRef ] ) {
26
+ let tcx = self . bcx . tcx ( ) ;
27
+ let mth_idx = option:: get ( ty:: method_idx ( "visit_" + ty_name,
28
+ * self . visitor_methods ) ) ;
29
+ let mth_ty = ty:: mk_fn ( tcx, self . visitor_methods [ mth_idx] . fty ) ;
30
+ let v = self . visitor_val ;
31
+ let get_lval = { |bcx|
32
+ impl:: trans_iface_callee ( bcx, v, mth_ty, mth_idx)
33
+ } ;
34
+ self . bcx =
35
+ trans_call_inner ( self . bcx , none, mth_ty, ty:: mk_bool ( tcx) ,
36
+ get_lval, arg_vals ( args) , ignore) ;
37
+ }
38
+
39
+ fn visit_tydesc ( t : ty:: t ) {
40
+ self . bcx =
41
+ call_tydesc_glue ( self . bcx , self . visitor_val , t,
42
+ abi:: tydesc_field_visit_glue) ;
43
+ }
44
+
45
+ fn bracketed_mt ( bracket_name : str , mt : ty:: mt , extra : [ ValueRef ] ) {
46
+ self . visit ( "enter_" + bracket_name,
47
+ [ self . c_uint ( mt. mutbl as uint ) ] + extra) ;
48
+ self . visit_tydesc ( mt. ty ) ;
49
+ self . visit ( "leave_" + bracket_name,
50
+ [ self . c_uint ( mt. mutbl as uint ) ] + extra) ;
51
+ }
40
52
41
- ty:: ty_vec ( mt) {
42
- let bcx = step ( bcx, "visit_vec_of" ,
43
- [ C_uint ( ccx, mt. mutbl as uint ) ] ) ;
44
- sub ( bcx, mt. ty )
45
- }
53
+ fn vstore_name_and_extra ( vstore : ty:: vstore ,
54
+ f : fn ( str , [ ValueRef ] ) ) {
55
+ alt vstore {
56
+ ty : : vstore_fixed ( n) { f ( "fixed" , [ self . c_uint ( n) ] ) }
57
+ ty:: vstore_slice ( _) { f ( "slice" , [ ] ) }
58
+ ty:: vstore_uniq { f( "uniq" , [ ] ) ; }
59
+ ty:: vstore_box { f( "box", [ ] ) ; }
60
+ }
61
+ }
46
62
47
- _ {
48
- // Ideally this would be an unimpl, but sadly we have
49
- // to pretend we can visit everything at this point.
50
- step ( bcx, "visit_bot" , [ ] )
51
- }
63
+ fn leaf ( name : str ) {
64
+ self . visit ( name, [ ] ) ;
65
+ }
66
+
67
+ // Entrypoint
68
+ fn visit_ty ( t : ty:: t ) {
69
+
70
+ alt ty:: get ( t) . struct {
71
+ ty:: ty_bot { self. leaf ( "bot" ) }
72
+ ty:: ty_nil { self. leaf ( "nil" ) }
73
+ ty:: ty_bool { self. leaf ( "bool" ) }
74
+ ty:: ty_int ( ast:: ty_i) { self . leaf ( "int" ) }
75
+ ty:: ty_int ( ast:: ty_char) { self . leaf ( "char" ) }
76
+ ty:: ty_int ( ast:: ty_i8) { self . leaf ( "i8" ) }
77
+ ty:: ty_int ( ast:: ty_i16) { self . leaf ( "i16" ) }
78
+ ty:: ty_int ( ast:: ty_i32) { self . leaf ( "i32" ) }
79
+ ty:: ty_int ( ast:: ty_i64) { self . leaf ( "i64" ) }
80
+ ty:: ty_uint ( ast:: ty_u) { self . leaf ( "uint" ) }
81
+ ty:: ty_uint ( ast:: ty_u8) { self . leaf ( "u8" ) }
82
+ ty:: ty_uint ( ast:: ty_u16) { self . leaf ( "u16" ) }
83
+ ty:: ty_uint ( ast:: ty_u32) { self . leaf ( "u32" ) }
84
+ ty:: ty_uint ( ast:: ty_u64) { self . leaf ( "u64" ) }
85
+ ty:: ty_float ( ast:: ty_f) { self . leaf ( "float" ) }
86
+ ty:: ty_float ( ast:: ty_f32) { self . leaf ( "f32" ) }
87
+ ty:: ty_float ( ast:: ty_f64) { self . leaf ( "f64" ) }
88
+ ty:: ty_str { self. leaf ( "str" ) }
89
+
90
+ ty:: ty_vec ( mt) { self . bracketed_mt ( "vec" , mt, [ ] ) }
91
+ ty:: ty_estr ( vst) {
92
+ self . vstore_name_and_extra ( vst) { |name, extra|
93
+ self . visit ( "estr_" + name, extra)
94
+ }
95
+ }
96
+ ty:: ty_evec ( mt, vst) {
97
+ self . vstore_name_and_extra ( vst) { |name, extra|
98
+ self . bracketed_mt ( "evec_" + name, mt, extra)
99
+ }
100
+ }
101
+ ty:: ty_box ( mt) { self . bracketed_mt ( "box" , mt, [ ] ) }
102
+ ty:: ty_uniq ( mt) { self . bracketed_mt ( "uniq" , mt, [ ] ) }
103
+ ty:: ty_ptr ( mt) { self . bracketed_mt ( "ptr" , mt, [ ] ) }
104
+ ty:: ty_rptr ( _, mt) { self . bracketed_mt ( "rptr" , mt, [ ] ) }
105
+
106
+ // FIXME: finish these.
107
+ _ { self . visit ( "bot" , [ ] ) }
108
+ }
52
109
}
53
110
}
54
111
55
112
// Emit a sequence of calls to visit_ty::visit_foo
56
113
fn emit_calls_to_iface_visit_ty ( bcx : block , t : ty:: t ,
57
114
visitor_val : ValueRef ,
58
115
visitor_iid : def_id ) -> block {
59
- let tcx = bcx. tcx ( ) ;
60
- let methods = ty:: iface_methods ( tcx, visitor_iid) ;
61
- visit_ty_steps ( bcx, t,
62
- { |bcx, mth_name, args|
63
- let mth_idx = option:: get ( ty:: method_idx ( mth_name,
64
- * methods) ) ;
65
- let mth_ty = ty:: mk_fn ( tcx, methods[ mth_idx] . fty ) ;
66
- let get_lval = { |bcx|
67
- impl:: trans_iface_callee ( bcx, visitor_val,
68
- mth_ty, mth_idx)
69
- } ;
70
- trans_call_inner ( bcx, none, mth_ty, ty:: mk_bool ( tcx) ,
71
- get_lval, arg_vals ( args) , ignore)
72
- } ,
73
- { |bcx, t_sub|
74
- call_tydesc_glue ( bcx, visitor_val, t_sub,
75
- abi:: tydesc_field_visit_glue) } )
116
+
117
+ let r = reflector ( {
118
+ visitor_val: visitor_val,
119
+ visitor_methods: ty:: iface_methods ( bcx. tcx ( ) , visitor_iid) ,
120
+ mut bcx: bcx
121
+ } ) ;
122
+
123
+ r. visit_ty ( t) ;
124
+ ret r. bcx ;
76
125
}
0 commit comments