Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fix a bug when returning a value using break inside #initialize would…

… not be returned from #new
  • Loading branch information...
commit 636eed71c8b2e6d28147cb83ce2abee687a99841 1 parent 85bdc0f
@lrz lrz authored
Showing with 23 additions and 11 deletions.
  1. +3 −1 array.c
  2. +11 −3 dispatcher.cpp
  3. +1 −1  object.c
  4. +3 −1 vm.h
  5. +5 −5 vm_eval.c
View
4 array.c
@@ -337,7 +337,9 @@ rary_initialize(VALUE ary, SEL sel, int argc, VALUE *argv)
rary_remove_all(RARY(ary));
for (long i = 0; i < len; i++) {
VALUE v = rb_yield(LONG2NUM(i));
- RETURN_IF_BROKEN();
+ if (BROKEN_VALUE() != Qundef) {
+ return ary;
+ }
rary_push(ary, v);
}
}
View
14 dispatcher.cpp
@@ -821,19 +821,24 @@ rb_vm_dispatch(void *_vm, struct mcache *cache, VALUE top, VALUE self,
SEL old_current_super_sel = vm->get_current_super_sel();
vm->set_current_super_sel(current_super_sel);
+ const bool should_pop_broken_with =
+ sel != selInitialize && sel != selInitialize2;
+
struct Finally {
bool block_already_current;
Class current_class;
Class current_super_class;
SEL current_super_sel;
+ bool should_pop_broken_with;
RoxorVM *vm;
Finally(bool _block_already_current, Class _current_class,
Class _current_super_class, SEL _current_super_sel,
- RoxorVM *_vm) {
+ bool _should_pop_broken_with, RoxorVM *_vm) {
block_already_current = _block_already_current;
current_class = _current_class;
current_super_class = _current_super_class;
current_super_sel = _current_super_sel;
+ should_pop_broken_with = _should_pop_broken_with;
vm = _vm;
}
~Finally() {
@@ -841,13 +846,16 @@ rb_vm_dispatch(void *_vm, struct mcache *cache, VALUE top, VALUE self,
vm->pop_current_block();
}
vm->set_current_class(current_class);
- vm->pop_broken_with();
+ if (should_pop_broken_with) {
+ vm->pop_broken_with();
+ }
vm->set_current_super_class(current_super_class);
vm->set_current_super_sel(current_super_sel);
vm->pop_current_binding();
}
} finalizer(block_already_current, current_klass,
- old_current_super_class, old_current_super_sel, vm);
+ old_current_super_class, old_current_super_sel,
+ should_pop_broken_with, vm);
// DTrace probe: method__entry
if (MACRUBY_METHOD_ENTRY_ENABLED()) {
View
2  object.c
@@ -2027,7 +2027,7 @@ rb_class_new_instance0(int argc, VALUE *argv, VALUE klass)
else {
rb_vm_call2(block, obj, CLASS_OF(obj), selInitialize2, argc, argv);
}
-
+ RETURN_IF_BROKEN();
return obj;
}
View
4 vm.h
@@ -516,9 +516,11 @@ void rb_vm_print_current_exception(void);
VALUE rb_vm_get_broken_value(void *vm);
VALUE rb_vm_returned_from_block(void *_vm, int id);
+#define BROKEN_VALUE() (rb_vm_get_broken_value(rb_vm_current_vm()))
+
#define ST_STOP_IF_BROKEN() \
do { \
- VALUE __v = rb_vm_get_broken_value(rb_vm_current_vm()); \
+ VALUE __v = BROKEN_VALUE(); \
if (__v != Qundef) { \
return ST_STOP; \
} \
View
10 vm_eval.c
@@ -121,14 +121,14 @@ rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
static VALUE
send_internal(int argc, VALUE *argv, VALUE recv, int scope)
{
- VALUE vid;
-
if (argc == 0) {
rb_raise(rb_eArgError, "no method name given");
}
-
- vid = *argv++; argc--;
- return rb_call(recv, rb_to_id(vid), argc, argv, scope, true);
+ VALUE vid = *argv++;
+ argc--;
+ VALUE retval = rb_call(recv, rb_to_id(vid), argc, argv, scope, true);
+ RETURN_IF_BROKEN();
+ return retval;
}
/*
Please sign in to comment.
Something went wrong with that request. Please try again.