Skip to content

Commit 56c6c65

Browse files
committed
Add preliminary test of walking data pointers via reflection.
1 parent 45f2926 commit 56c6c65

File tree

1 file changed

+303
-0
lines changed

1 file changed

+303
-0
lines changed
Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
import libc::c_void;
2+
3+
iface data_cursor {
4+
fn set_ptr(p: *c_void);
5+
fn get_ptr() -> *c_void;
6+
}
7+
8+
enum my_visitor = @{
9+
mut ptr: *c_void,
10+
mut vals: [str]
11+
};
12+
13+
impl methods for my_visitor {
14+
fn get<T>(f: fn(T)) {
15+
unsafe {
16+
f(*(self.ptr as *T));
17+
}
18+
}
19+
}
20+
21+
impl of data_cursor for my_visitor {
22+
fn set_ptr(p: *c_void) { self.ptr = p; }
23+
fn get_ptr() -> *c_void { self.ptr }
24+
}
25+
26+
impl of intrinsic::ty_visitor for my_visitor {
27+
28+
fn visit_bot() -> bool { true }
29+
fn visit_nil() -> bool { true }
30+
fn visit_bool() -> bool {
31+
self.get::<bool>() {|b|
32+
self.vals += [bool::to_str(b)];
33+
}
34+
true
35+
}
36+
fn visit_int() -> bool {
37+
self.get::<int>() {|i|
38+
self.vals += [int::to_str(i, 10u)];
39+
}
40+
true
41+
}
42+
fn visit_i8() -> bool { true }
43+
fn visit_i16() -> bool { true }
44+
fn visit_i32() -> bool { true }
45+
fn visit_i64() -> bool { true }
46+
47+
fn visit_uint() -> bool { true }
48+
fn visit_u8() -> bool { true }
49+
fn visit_u16() -> bool { true }
50+
fn visit_u32() -> bool { true }
51+
fn visit_u64() -> bool { true }
52+
53+
fn visit_float() -> bool { true }
54+
fn visit_f32() -> bool { true }
55+
fn visit_f64() -> bool { true }
56+
57+
fn visit_char() -> bool { true }
58+
fn visit_str() -> bool { true }
59+
60+
fn visit_estr_box() -> bool { true }
61+
fn visit_estr_uniq() -> bool { true }
62+
fn visit_estr_slice() -> bool { true }
63+
fn visit_estr_fixed(_sz: uint) -> bool { true }
64+
65+
fn visit_enter_box(_mtbl: uint) -> bool { true }
66+
fn visit_leave_box(_mtbl: uint) -> bool { true }
67+
fn visit_enter_uniq(_mtbl: uint) -> bool { true }
68+
fn visit_leave_uniq(_mtbl: uint) -> bool { true }
69+
fn visit_enter_ptr(_mtbl: uint) -> bool { true }
70+
fn visit_leave_ptr(_mtbl: uint) -> bool { true }
71+
fn visit_enter_rptr(_mtbl: uint) -> bool { true }
72+
fn visit_leave_rptr(_mtbl: uint) -> bool { true }
73+
74+
fn visit_enter_vec(_mtbl: uint) -> bool { true }
75+
fn visit_leave_vec(_mtbl: uint) -> bool { true }
76+
fn visit_enter_evec_box(_mtbl: uint) -> bool { true }
77+
fn visit_leave_evec_box(_mtbl: uint) -> bool { true }
78+
fn visit_enter_evec_uniq(_mtbl: uint) -> bool { true }
79+
fn visit_leave_evec_uniq(_mtbl: uint) -> bool { true }
80+
fn visit_enter_evec_slice(_mtbl: uint) -> bool { true }
81+
fn visit_leave_evec_slice(_mtbl: uint) -> bool { true }
82+
fn visit_enter_evec_fixed(_mtbl: uint, _sz: uint) -> bool { true }
83+
fn visit_leave_evec_fixed(_mtbl: uint, _sz: uint) -> bool { true }
84+
85+
fn visit_enter_rec(_n_fields: uint) -> bool { true }
86+
fn visit_enter_rec_field(_mtbl: uint, _i: uint,
87+
_name: str/&) -> bool { true }
88+
fn visit_leave_rec_field(_mtbl: uint, _i: uint,
89+
_name: str/&) -> bool { true }
90+
fn visit_leave_rec(_n_fields: uint) -> bool { true }
91+
92+
fn visit_enter_class(_n_fields: uint) -> bool { true }
93+
fn visit_enter_class_field(_mtbl: uint, _i: uint,
94+
_name: str/&) -> bool { true }
95+
fn visit_leave_class_field(_mtbl: uint, _i: uint,
96+
_name: str/&) -> bool { true }
97+
fn visit_leave_class(_n_fields: uint) -> bool { true }
98+
99+
fn visit_enter_tup(_n_fields: uint) -> bool { true }
100+
fn visit_enter_tup_field(_i: uint) -> bool { true }
101+
fn visit_leave_tup_field(_i: uint) -> bool { true }
102+
fn visit_leave_tup(_n_fields: uint) -> bool { true }
103+
104+
fn visit_enter_fn(_purity: uint, _proto: uint,
105+
_n_inputs: uint, _retstyle: uint) -> bool { true }
106+
fn visit_enter_fn_input(_i: uint, _mode: uint) -> bool { true }
107+
fn visit_leave_fn_input(_i: uint, _mode: uint) -> bool { true }
108+
fn visit_enter_fn_output(_retstyle: uint) -> bool { true }
109+
fn visit_leave_fn_output(_retstyle: uint) -> bool { true }
110+
fn visit_leave_fn(_purity: uint, _proto: uint,
111+
_n_inputs: uint, _retstyle: uint) -> bool { true }
112+
113+
fn visit_enter_enum(_n_variants: uint) -> bool { true }
114+
fn visit_enter_enum_variant(_variant: uint,
115+
_disr_val: int,
116+
_n_fields: uint,
117+
_name: str/&) -> bool { true }
118+
fn visit_enter_enum_variant_field(_i: uint) -> bool { true }
119+
fn visit_leave_enum_variant_field(_i: uint) -> bool { true }
120+
fn visit_leave_enum_variant(_variant: uint,
121+
_disr_val: int,
122+
_n_fields: uint,
123+
_name: str/&) -> bool { true }
124+
fn visit_leave_enum(_n_variants: uint) -> bool { true }
125+
126+
fn visit_iface() -> bool { true }
127+
fn visit_enter_res() -> bool { true }
128+
fn visit_leave_res() -> bool { true }
129+
fn visit_var() -> bool { true }
130+
fn visit_var_integral() -> bool { true }
131+
fn visit_param(_i: uint) -> bool { true }
132+
fn visit_self() -> bool { true }
133+
fn visit_type() -> bool { true }
134+
fn visit_opaque_box() -> bool { true }
135+
fn visit_enter_constr() -> bool { true }
136+
fn visit_leave_constr() -> bool { true }
137+
fn visit_closure_ptr(_ck: uint) -> bool { true }
138+
}
139+
140+
enum data_visitor<V:intrinsic::ty_visitor data_cursor> = {
141+
inner: V
142+
};
143+
144+
fn align_to<T>(size: uint, align: uint) -> uint {
145+
((size + align) - 1u) & !(align - 1u)
146+
}
147+
148+
impl dv<V: intrinsic::ty_visitor data_cursor> of
149+
intrinsic::ty_visitor for data_visitor<V> {
150+
151+
fn move_ptr(f: fn(*c_void) -> *c_void) {
152+
self.inner.set_ptr(f(self.inner.get_ptr()));
153+
}
154+
155+
fn bump(sz: uint) {
156+
self.move_ptr() {|p|
157+
((p as uint) + sz) as *c_void
158+
}
159+
}
160+
161+
fn align_to<T>() {
162+
self.move_ptr() {|p|
163+
align_to::<T>(p as uint,
164+
sys::min_align_of::<T>()) as *c_void
165+
}
166+
}
167+
168+
fn bump_past<T>() {
169+
self.bump(sys::size_of::<T>());
170+
}
171+
172+
fn visit_bot() -> bool {
173+
self.align_to::<bool>();
174+
self.inner.visit_bot();
175+
self.bump_past::<bool>();
176+
true
177+
}
178+
fn visit_nil() -> bool { true }
179+
fn visit_bool() -> bool {
180+
self.align_to::<bool>();
181+
self.inner.visit_bool();
182+
self.bump_past::<bool>();
183+
true
184+
}
185+
fn visit_int() -> bool {
186+
self.align_to::<int>();
187+
self.inner.visit_int();
188+
self.bump_past::<int>();
189+
true
190+
}
191+
fn visit_i8() -> bool { true }
192+
fn visit_i16() -> bool { true }
193+
fn visit_i32() -> bool { true }
194+
fn visit_i64() -> bool { true }
195+
196+
fn visit_uint() -> bool { true }
197+
fn visit_u8() -> bool { true }
198+
fn visit_u16() -> bool { true }
199+
fn visit_u32() -> bool { true }
200+
fn visit_u64() -> bool { true }
201+
202+
fn visit_float() -> bool { true }
203+
fn visit_f32() -> bool { true }
204+
fn visit_f64() -> bool { true }
205+
206+
fn visit_char() -> bool { true }
207+
fn visit_str() -> bool { true }
208+
209+
fn visit_estr_box() -> bool { true }
210+
fn visit_estr_uniq() -> bool { true }
211+
fn visit_estr_slice() -> bool { true }
212+
fn visit_estr_fixed(_sz: uint) -> bool { true }
213+
214+
fn visit_enter_box(_mtbl: uint) -> bool { true }
215+
fn visit_leave_box(_mtbl: uint) -> bool { true }
216+
fn visit_enter_uniq(_mtbl: uint) -> bool { true }
217+
fn visit_leave_uniq(_mtbl: uint) -> bool { true }
218+
fn visit_enter_ptr(_mtbl: uint) -> bool { true }
219+
fn visit_leave_ptr(_mtbl: uint) -> bool { true }
220+
fn visit_enter_rptr(_mtbl: uint) -> bool { true }
221+
fn visit_leave_rptr(_mtbl: uint) -> bool { true }
222+
223+
fn visit_enter_vec(_mtbl: uint) -> bool { true }
224+
fn visit_leave_vec(_mtbl: uint) -> bool { true }
225+
fn visit_enter_evec_box(_mtbl: uint) -> bool { true }
226+
fn visit_leave_evec_box(_mtbl: uint) -> bool { true }
227+
fn visit_enter_evec_uniq(_mtbl: uint) -> bool { true }
228+
fn visit_leave_evec_uniq(_mtbl: uint) -> bool { true }
229+
fn visit_enter_evec_slice(_mtbl: uint) -> bool { true }
230+
fn visit_leave_evec_slice(_mtbl: uint) -> bool { true }
231+
fn visit_enter_evec_fixed(_mtbl: uint, _sz: uint) -> bool { true }
232+
fn visit_leave_evec_fixed(_mtbl: uint, _sz: uint) -> bool { true }
233+
234+
fn visit_enter_rec(_n_fields: uint) -> bool { true }
235+
fn visit_enter_rec_field(_mtbl: uint, _i: uint,
236+
_name: str/&) -> bool { true }
237+
fn visit_leave_rec_field(_mtbl: uint, _i: uint,
238+
_name: str/&) -> bool { true }
239+
fn visit_leave_rec(_n_fields: uint) -> bool { true }
240+
241+
fn visit_enter_class(_n_fields: uint) -> bool { true }
242+
fn visit_enter_class_field(_mtbl: uint, _i: uint,
243+
_name: str/&) -> bool { true }
244+
fn visit_leave_class_field(_mtbl: uint, _i: uint,
245+
_name: str/&) -> bool { true }
246+
fn visit_leave_class(_n_fields: uint) -> bool { true }
247+
248+
fn visit_enter_tup(_n_fields: uint) -> bool { true }
249+
fn visit_enter_tup_field(_i: uint) -> bool { true }
250+
fn visit_leave_tup_field(_i: uint) -> bool { true }
251+
fn visit_leave_tup(_n_fields: uint) -> bool { true }
252+
253+
fn visit_enter_fn(_purity: uint, _proto: uint,
254+
_n_inputs: uint, _retstyle: uint) -> bool { true }
255+
fn visit_enter_fn_input(_i: uint, _mode: uint) -> bool { true }
256+
fn visit_leave_fn_input(_i: uint, _mode: uint) -> bool { true }
257+
fn visit_enter_fn_output(_retstyle: uint) -> bool { true }
258+
fn visit_leave_fn_output(_retstyle: uint) -> bool { true }
259+
fn visit_leave_fn(_purity: uint, _proto: uint,
260+
_n_inputs: uint, _retstyle: uint) -> bool { true }
261+
262+
fn visit_enter_enum(_n_variants: uint) -> bool { true }
263+
fn visit_enter_enum_variant(_variant: uint,
264+
_disr_val: int,
265+
_n_fields: uint,
266+
_name: str/&) -> bool { true }
267+
fn visit_enter_enum_variant_field(_i: uint) -> bool { true }
268+
fn visit_leave_enum_variant_field(_i: uint) -> bool { true }
269+
fn visit_leave_enum_variant(_variant: uint,
270+
_disr_val: int,
271+
_n_fields: uint,
272+
_name: str/&) -> bool { true }
273+
fn visit_leave_enum(_n_variants: uint) -> bool { true }
274+
275+
fn visit_iface() -> bool { true }
276+
fn visit_enter_res() -> bool { true }
277+
fn visit_leave_res() -> bool { true }
278+
fn visit_var() -> bool { true }
279+
fn visit_var_integral() -> bool { true }
280+
fn visit_param(_i: uint) -> bool { true }
281+
fn visit_self() -> bool { true }
282+
fn visit_type() -> bool { true }
283+
fn visit_opaque_box() -> bool { true }
284+
fn visit_enter_constr() -> bool { true }
285+
fn visit_leave_constr() -> bool { true }
286+
fn visit_closure_ptr(_ck: uint) -> bool { true }
287+
}
288+
289+
fn main() {
290+
let r = (1,2,3,true,false);
291+
let p = ptr::addr_of(r) as *c_void;
292+
let u = my_visitor(@{mut ptr: p,
293+
mut vals: []});
294+
let v = data_visitor({inner: u});
295+
let vv = v as intrinsic::ty_visitor;
296+
intrinsic::visit_ty::<(int,int,int,bool,bool)>(vv);
297+
298+
for u.vals.each {|s|
299+
io::println(#fmt("val: %s", s));
300+
}
301+
assert u.vals == ["1", "2", "3", "true", "false"];
302+
303+
}

0 commit comments

Comments
 (0)