Revision: 1914 http://trac.macosforge.org/projects/ruby/changeset/1914 Author: vincent.isambart@gmail.com Date: 2009-06-20 18:45:04 -0700 (Sat, 20 Jun 2009) Log Message: ----------- added a failing test and its fix Modified Paths: -------------- MacRuby/branches/experimental/test_vm/block.rb MacRuby/branches/experimental/vm.cpp Modified: MacRuby/branches/experimental/test_vm/block.rb =================================================================== --- MacRuby/branches/experimental/test_vm/block.rb 2009-06-20 23:43:28 UTC (rev 1913) +++ MacRuby/branches/experimental/test_vm/block.rb 2009-06-21 01:45:04 UTC (rev 1914) @@ -532,3 +532,8 @@ } assert '[2, 3, 4]', "p [1, 2, 3].map(&:succ)" + +assert '42', %{ + b = proc { |x| if x then p x else b.call(42) end } + b.call(nil) +} Modified: MacRuby/branches/experimental/vm.cpp =================================================================== --- MacRuby/branches/experimental/vm.cpp 2009-06-20 23:43:28 UTC (rev 1913) +++ MacRuby/branches/experimental/vm.cpp 2009-06-21 01:45:04 UTC (rev 1914) @@ -2756,6 +2756,36 @@ extern "C" rb_vm_block_t * +rb_vm_dup_active_block(rb_vm_block_t *src_b) +{ + assert(src_b->flags & VM_BLOCK_ACTIVE); + + int block_size = sizeof(rb_vm_block_t) + + (sizeof(VALUE *) * src_b->dvars_size); + + rb_vm_block_t *new_b = (rb_vm_block_t *)xmalloc(block_size); + + memcpy(new_b, src_b, block_size); + GC_WB(&new_b->parent_block, src_b->parent_block); + new_b->flags = src_b->flags & ~VM_BLOCK_ACTIVE; + + rb_vm_local_t *src_l = src_b->locals; + rb_vm_local_t **new_l = &new_b->locals; + while (src_l != NULL) { + GC_WB(new_l, xmalloc(sizeof(rb_vm_local_t))); + (*new_l)->name = src_l->name; + GC_WB(&(*new_l)->value, src_l->value); + + new_l = &(*new_l)->next; + src_l = src_l->next; + } + *new_l = NULL; + + return new_b; +} + +extern "C" +rb_vm_block_t * rb_vm_prepare_block(void *llvm_function, NODE *node, VALUE self, rb_vm_var_uses **parent_var_uses, rb_vm_block_t *parent_block, @@ -2834,7 +2864,7 @@ for (int i = 0; i < lvars_size; ++i) { assert(l != NULL); l->name = va_arg(ar, ID); - l->value = va_arg(ar, VALUE *); + GC_WB(&l->value, va_arg(ar, VALUE *)); l = l->next; } } @@ -3273,7 +3303,9 @@ block_call: - assert(!(b->flags & VM_BLOCK_ACTIVE)); + if (b->flags & VM_BLOCK_ACTIVE) { + b = rb_vm_dup_active_block(b); + } b->flags |= VM_BLOCK_ACTIVE; VALUE v = Qnil; try {