Revision: 1055 http://trac.macosforge.org/projects/ruby/changeset/1055 Author: lsansonetti@apple.com Date: 2009-03-21 19:28:17 -0700 (Sat, 21 Mar 2009) Log Message: ----------- do not stack blocks since this doesn't go well with the ruby semantics Modified Paths: -------------- MacRuby/branches/experimental/include/ruby/ruby.h MacRuby/branches/experimental/proc.c MacRuby/branches/experimental/roxor.cpp MacRuby/branches/experimental/roxor.h MacRuby/branches/experimental/test_roxor.rb MacRuby/branches/experimental/vm_eval.c Modified: MacRuby/branches/experimental/include/ruby/ruby.h =================================================================== --- MacRuby/branches/experimental/include/ruby/ruby.h 2009-03-22 01:17:49 UTC (rev 1054) +++ MacRuby/branches/experimental/include/ruby/ruby.h 2009-03-22 02:28:17 UTC (rev 1055) @@ -962,8 +962,8 @@ void rb_need_block(void); VALUE rb_iterate(VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE); VALUE rb_block_call(VALUE,ID,int,VALUE*,VALUE(*)(ANYARGS),VALUE); -VALUE rb_objc_block_call(VALUE obj, SEL sel, int argc, VALUE *argv, - VALUE (*bl_proc) (ANYARGS), VALUE data2); +VALUE rb_objc_block_call(VALUE obj, SEL sel, void *cache, int argc, + VALUE *argv, VALUE (*bl_proc) (ANYARGS), VALUE data2); VALUE rb_rescue(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE); VALUE rb_rescue2(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE,...); VALUE rb_ensure(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE); Modified: MacRuby/branches/experimental/proc.c =================================================================== --- MacRuby/branches/experimental/proc.c 2009-03-22 01:17:49 UTC (rev 1054) +++ MacRuby/branches/experimental/proc.c 2009-03-22 02:28:17 UTC (rev 1055) @@ -1119,7 +1119,7 @@ } } - VALUE result = rb_vm_call_with_cache2(data->cache, data->recv, + VALUE result = rb_vm_call_with_cache2(data->cache, data->recv, data->oclass, data->sel, argc, argv); if (safe >= 0) { Modified: MacRuby/branches/experimental/roxor.cpp =================================================================== --- MacRuby/branches/experimental/roxor.cpp 2009-03-22 01:17:49 UTC (rev 1054) +++ MacRuby/branches/experimental/roxor.cpp 2009-03-22 02:28:17 UTC (rev 1055) @@ -383,7 +383,6 @@ std::map<ID, struct ccache *> ccache; std::map<Class, std::map<ID, int> *> ivar_slots; std::map<SEL, GlobalVariable *> redefined_ops_gvars; - std::stack<rb_vm_block_t *> current_blocks; public: static RoxorVM *current; @@ -399,14 +398,11 @@ std::map<NODE *, rb_vm_block_t *> blocks; std::map<double, struct rb_float_cache *> float_cache; unsigned char method_missing_reason; + rb_vm_block_t *current_block; + rb_vm_block_t *previous_block; // only used for non-Ruby created blocks RoxorVM(void); - rb_vm_block_t *top_block(void) { return current_blocks.top(); } - bool block_given(void) { return !current_blocks.empty(); } - void push_block(rb_vm_block_t *b) { current_blocks.push(b); } - void pop_block(void) { current_blocks.pop(); } - ExecutionEngine *execution_engine(void) { return ee; } IMP compile(Function *func, bool optimize=true) { @@ -1776,6 +1772,9 @@ backref = Qnil; broken_with = Qundef; + current_block = NULL; + previous_block = NULL; + load_path = rb_ary_new(); rb_objc_retain((void *)load_path); loaded_features = rb_ary_new(); @@ -4744,10 +4743,11 @@ if (block != NULL) { rb_vm_block_t *b = (rb_vm_block_t *)block; - GET_VM()->push_block(b); + rb_vm_block_t *old_b = GET_VM()->current_block; + GET_VM()->current_block = b; VALUE retval = __rb_vm_dispatch(cache, self, NULL, sel, opt, argc, argv); - GET_VM()->pop_block(); + GET_VM()->current_block = old_b; return retval; } @@ -4947,8 +4947,8 @@ extern "C" VALUE -rb_vm_call_with_cache2(void *cache, VALUE self, VALUE klass, SEL sel, int argc, - const VALUE *argv) +rb_vm_call_with_cache2(void *cache, VALUE self, VALUE klass, SEL sel, + int argc, const VALUE *argv) { return __rb_vm_dispatch((struct mcache *)cache, self, (Class)klass, sel, 0, argc, argv); @@ -4965,28 +4965,30 @@ int rb_block_given_p(void) { - return GET_VM()->block_given() ? Qtrue : Qfalse; + return GET_VM()->current_block != NULL ? Qtrue : Qfalse; } extern "C" rb_vm_block_t * rb_vm_current_block(void) { - return GET_VM()->top_block(); + return GET_VM()->current_block; } extern "C" void -rb_vm_push_block(rb_vm_block_t *block) +rb_vm_change_current_block(rb_vm_block_t *block) { - GET_VM()->push_block(block); + GET_VM()->previous_block = GET_VM()->current_block; + GET_VM()->current_block = block; } extern "C" void -rb_vm_pop_block(void) +rb_vm_restore_current_block(void) { - GET_VM()->pop_block(); + GET_VM()->current_block = GET_VM()->previous_block; + GET_VM()->previous_block = NULL; } extern "C" VALUE rb_proc_alloc_with_block(VALUE klass, rb_vm_block_t *proc); @@ -4995,8 +4997,8 @@ VALUE rb_vm_current_block_object(void) { - if (GET_VM()->block_given()) { - return rb_proc_alloc_with_block(rb_cProc, GET_VM()->top_block()); + if (GET_VM()->current_block != NULL) { + return rb_proc_alloc_with_block(rb_cProc, GET_VM()->current_block); } return Qnil; } @@ -5158,11 +5160,15 @@ static inline VALUE rb_vm_yield0(int argc, const VALUE *argv) { - rb_vm_block_t *b = GET_VM()->top_block(); + rb_vm_block_t *b = GET_VM()->current_block; - GET_VM()->pop_block(); + if (b == NULL) { + rb_raise(rb_eLocalJumpError, "no block given"); + } + + GET_VM()->current_block = GET_VM()->previous_block; VALUE retval = rb_vm_block_eval0(b, argc, argv); - GET_VM()->push_block(b); + GET_VM()->current_block = b; return retval; } @@ -5178,9 +5184,9 @@ VALUE rb_vm_yield_under(VALUE klass, VALUE self, int argc, const VALUE *argv) { - rb_vm_block_t *b = GET_VM()->top_block(); + rb_vm_block_t *b = GET_VM()->current_block; - GET_VM()->pop_block(); + GET_VM()->current_block = NULL; VALUE old_self = b->self; b->self = self; @@ -5189,7 +5195,7 @@ VALUE retval = rb_vm_block_eval0(b, argc, argv); b->self = old_self; - GET_VM()->push_block(b); + GET_VM()->current_block = b; return retval; } Modified: MacRuby/branches/experimental/roxor.h =================================================================== --- MacRuby/branches/experimental/roxor.h 2009-03-22 01:17:49 UTC (rev 1054) +++ MacRuby/branches/experimental/roxor.h 2009-03-22 02:28:17 UTC (rev 1055) @@ -112,8 +112,8 @@ rb_vm_block_t *rb_vm_prepare_block(void *llvm_function, NODE *node, VALUE self, int dvars_size, ...); rb_vm_block_t *rb_vm_current_block(void); -void rb_vm_push_block(rb_vm_block_t *block); -void rb_vm_pop_block(void); +void rb_vm_change_current_block(rb_vm_block_t *block); +void rb_vm_restore_current_block(void); VALUE rb_vm_block_eval(rb_vm_block_t *block, int argc, const VALUE *argv); struct rb_float_cache { Modified: MacRuby/branches/experimental/test_roxor.rb =================================================================== --- MacRuby/branches/experimental/test_roxor.rb 2009-03-22 01:17:49 UTC (rev 1054) +++ MacRuby/branches/experimental/test_roxor.rb 2009-03-22 02:28:17 UTC (rev 1055) @@ -847,10 +847,12 @@ foo { |a = 42, *rest| p [a, rest] } } - assert ":ok", "def foo; p :ok if block_given?; end; foo {}" - assert ":ok", "def foo; p :ok unless block_given?; end; foo" - assert ":ok", "def foo; p block_given?; end; def bar; foo; end; bar {}" + assert "true", "def foo; p block_given?; end; foo {}" + assert "false", "def foo; p block_given?; end; foo" + assert "true", "def foo; p block_given?; end; def bar; foo; end; bar {}" + assert ':ok', "def foo; yield; end; begin; foo; rescue LocalJumpError; p :ok; end" + assert ":ok", "def foo(&m); m.call; end; foo { p :ok }" assert ":ok", "def foo(&m); p :ok if m == nil; end; foo" Modified: MacRuby/branches/experimental/vm_eval.c =================================================================== --- MacRuby/branches/experimental/vm_eval.c 2009-03-22 01:17:49 UTC (rev 1054) +++ MacRuby/branches/experimental/vm_eval.c 2009-03-22 02:28:17 UTC (rev 1055) @@ -274,16 +274,17 @@ } VALUE -rb_objc_block_call(VALUE obj, SEL sel, int argc, VALUE *argv, +rb_objc_block_call(VALUE obj, SEL sel, void *cache, int argc, VALUE *argv, VALUE (*bl_proc) (ANYARGS), VALUE data2) { NODE *node = NEW_IFUNC(bl_proc, data2); rb_vm_block_t *b = rb_vm_prepare_block(NULL, node, obj, 0); - - rb_vm_push_block(b); - VALUE val = rb_vm_call(obj, sel, argc, argv, false); - rb_vm_pop_block(); - + rb_vm_change_current_block(b); + if (cache == NULL) { + cache = rb_vm_get_call_cache(sel); + } + VALUE val = rb_vm_call_with_cache2(cache, obj, 0, sel, argc, argv); + rb_vm_restore_current_block(); return val; } @@ -300,7 +301,7 @@ snprintf(buf, sizeof buf, "%s:", rb_id2name(mid)); sel = sel_registerName(buf); } - return rb_objc_block_call(obj, sel, argc, argv, bl_proc, data2); + return rb_objc_block_call(obj, sel, NULL, argc, argv, bl_proc, data2); } VALUE