|
| 1 | +use std::marker::PhantomData; |
| 2 | + |
1 | 3 | use crate::mmtk;
|
2 | 4 | use crate::upcalls;
|
3 | 5 | use crate::Ruby;
|
@@ -25,16 +27,39 @@ impl ActivePlan<Ruby> for VMActivePlan {
|
25 | 27 | unimplemented!()
|
26 | 28 | }
|
27 | 29 |
|
28 |
| - fn reset_mutator_iterator() { |
29 |
| - (upcalls().reset_mutator_iterator)(); |
| 30 | + fn mutators<'a>() -> Box<dyn Iterator<Item = &'a mut Mutator<Ruby>> + 'a> { |
| 31 | + let mut mutators = vec![]; |
| 32 | + (upcalls().get_mutators)( |
| 33 | + add_mutator_to_vec, |
| 34 | + &mut mutators as *mut Vec<*mut Mutator<Ruby>> as _, |
| 35 | + ); |
| 36 | + |
| 37 | + Box::new(RubyMutatorIterator { |
| 38 | + mutators, |
| 39 | + cursor: 0, |
| 40 | + phantom_data: PhantomData, |
| 41 | + }) |
30 | 42 | }
|
| 43 | +} |
| 44 | + |
| 45 | +extern "C" fn add_mutator_to_vec(mutator: *mut Mutator<Ruby>, mutators: *mut libc::c_void) { |
| 46 | + let mutators = unsafe { &mut *(mutators as *mut Vec<*mut Mutator<Ruby>>) }; |
| 47 | + mutators.push(mutator); |
| 48 | +} |
| 49 | + |
| 50 | +struct RubyMutatorIterator<'a> { |
| 51 | + mutators: Vec<*mut Mutator<Ruby>>, |
| 52 | + cursor: usize, |
| 53 | + phantom_data: PhantomData<&'a ()>, |
| 54 | +} |
| 55 | + |
| 56 | +impl<'a> Iterator for RubyMutatorIterator<'a> { |
| 57 | + type Item = &'a mut Mutator<Ruby>; |
31 | 58 |
|
32 |
| - fn get_next_mutator() -> Option<&'static mut Mutator<Ruby>> { |
33 |
| - let ptr = (upcalls().get_next_mutator)(); |
34 |
| - if ptr.is_null() { |
35 |
| - None |
36 |
| - } else { |
37 |
| - Some(unsafe { &mut (*ptr) as &'static mut Mutator<Ruby> }) |
38 |
| - } |
| 59 | + fn next(&mut self) -> Option<Self::Item> { |
| 60 | + self.mutators.get(self.cursor).cloned().map(|mutator_ptr| { |
| 61 | + self.cursor += 1; |
| 62 | + unsafe { &mut *mutator_ptr as _ } |
| 63 | + }) |
39 | 64 | }
|
40 | 65 | }
|
0 commit comments