Revision: 2814 http://trac.macosforge.org/projects/ruby/changeset/2814 Author: lsansonetti@apple.com Date: 2009-10-15 14:14:30 -0700 (Thu, 15 Oct 2009) Log Message: ----------- implement rb_exec_recursive() Modified Paths: -------------- MacRuby/trunk/array.c MacRuby/trunk/vm.cpp MacRuby/trunk/vm.h Modified: MacRuby/trunk/array.c =================================================================== --- MacRuby/trunk/array.c 2009-10-15 20:10:33 UTC (rev 2813) +++ MacRuby/trunk/array.c 2009-10-15 21:14:30 UTC (rev 2814) @@ -1658,13 +1658,6 @@ } VALUE -rb_exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg) -{ - // TODO check! - return (*func) (obj, arg, Qfalse); -} - -VALUE rb_ary_join(VALUE ary, VALUE sep) { long i, count; Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2009-10-15 20:10:33 UTC (rev 2813) +++ MacRuby/trunk/vm.cpp 2009-10-15 21:14:30 UTC (rev 2814) @@ -3549,6 +3549,35 @@ } extern "C" +VALUE +rb_exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE arg) +{ + return GET_VM()->exec_recursive(func, obj, arg); +} + +VALUE +RoxorVM::exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, + VALUE arg) +{ + std::vector<VALUE>::iterator iter = + std::find(recursive_objects.begin(), recursive_objects.end(), obj); + if (iter != recursive_objects.end()) { + // Object is already being iterated! + return (*func) (obj, arg, Qtrue); + } + + recursive_objects.push_back(obj); + // XXX the function is not supposed to raise an exception. + VALUE ret = (*func) (obj, arg, Qfalse); + + iter = std::find(recursive_objects.begin(), recursive_objects.end(), obj); + assert(iter != recursive_objects.end()); + recursive_objects.erase(iter); + + return ret; +} + +extern "C" void * rb_vm_create_vm(void) { Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2009-10-15 20:10:33 UTC (rev 2813) +++ MacRuby/trunk/vm.h 2009-10-15 21:14:30 UTC (rev 2814) @@ -808,6 +808,7 @@ std::vector<VALUE> current_exceptions; std::vector<rb_vm_binding_t *> bindings; std::map<VALUE, rb_vm_catch_t *> catch_jmp_bufs; + std::vector<VALUE> recursive_objects; VALUE thread; Class current_class; @@ -932,6 +933,9 @@ VALUE ruby_throw(VALUE tag, VALUE value); void setup_from_current_thread(void); + + VALUE exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, + VALUE arg); }; #define GET_VM() (RoxorVM::current())